aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-10-04 13:26:38 -0400
committerDavid S. Miller <davem@davemloft.net>2013-10-04 13:26:38 -0400
commitd639feaaf3f40cd90b75a2fec5b7d5c3f96c2c88 (patch)
tree1517467ea9853f0bd61923dd619c1c937b80673c
parent96f817fedec48b59c9e8b22141cec4e56ad47913 (diff)
parent91cb498e6a34b429a032f8cfbb57dde28cd20e0c (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 Netfilter updates for your net-next tree, mostly ipset improvements and enhancements features, they are: * Don't call ip_nest_end needlessly in the error path from me, suggested by Pablo Neira Ayuso, from Jozsef Kadlecsik. * Fixed sparse warnings about shadowed variable and missing rcu annotation and fix of "may be used uninitialized" warnings, also from Jozsef. * Renamed simple macro names to avoid namespace issues, reported by David Laight, again from Jozsef. * Use fix sized type for timeout in the extension part, and cosmetic ordering of matches and targets separatedly in xt_set.c, from Jozsef. * Support package fragments for IPv4 protos without ports from Anders K. Pedersen. For example this allows a hash:ip,port ipset containing the entry 192.168.0.1,gre:0 to match all package fragments for PPTP VPN tunnels to/from the host. Without this patch only the first package fragment (with fragment offset 0) was matched. * Introduced a new operation to get both setname and family, from Jozsef. ip[6]tables set match and SET target need to know the family of the set in order to reject adding rules which refer to a set with a non-mathcing family. Currently such rules are silently accepted and then ignored instead of generating an error message to the user. * Reworked extensions support in ipset types from Jozsef. The approach of defining structures with all variations is not manageable as the number of extensions grows. Therefore a blob for the extensions is introduced, somewhat similar to conntrack. The support of extensions which need a per data destroy function is added as well. * When an element timed out in a list:set type of set, the garbage collector skipped the checking of the next element. So the purging was delayed to the next run of the gc, fixed by Jozsef. * A small Kconfig fix: NETFILTER_NETLINK cannot be selected and ipset requires it. * hash:net,net type from Oliver Smith. The type provides the ability to store pairs of subnets in a set. * Comment for ipset entries from Oliver Smith. This makes possible to annotate entries in a set with comments, for example: ipset n foo hash:net,net comment ipset a foo 10.0.0.0/21,192.168.1.0/24 comment "office nets A and B" * Fix of hash types resizing with comment extension from Jozsef. * Fix of new extensions for list:set type when an element is added into a slot from where another element was pushed away from Jozsef. * Introduction of a common function for the listing of the element extensions from Jozsef. * Net namespace support for ipset from Vitaly Lavrov. * hash:net,port,net type from Oliver Smith, which makes possible to store the triples of two subnets and a protocol, port pair in a set. * Get xt_TCPMSS working with net namespace, by Gao feng. * Use the proper net netnamespace to allocate skbs, also by Gao feng. * A couple of cleanups for the conntrack SIP helper, by Holger Eitzenberger. * Extend cttimeout to allow setting default conntrack timeouts via nfnetlink, so we can get rid of all our sysctl/proc interfaces in the future for timeout tuning, from me. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netfilter/ipset/ip_set.h151
-rw-r--r--include/linux/netfilter/ipset/ip_set_comment.h57
-rw-r--r--include/linux/netfilter/ipset/ip_set_timeout.h4
-rw-r--r--include/linux/netfilter/nf_conntrack_sip.h107
-rw-r--r--include/uapi/linux/netfilter/ipset/ip_set.h16
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_cttimeout.h2
-rw-r--r--net/netfilter/ipset/Kconfig20
-rw-r--r--net/netfilter/ipset/Makefile2
-rw-r--r--net/netfilter/ipset/ip_set_bitmap_gen.h163
-rw-r--r--net/netfilter/ipset/ip_set_bitmap_ip.c125
-rw-r--r--net/netfilter/ipset/ip_set_bitmap_ipmac.c156
-rw-r--r--net/netfilter/ipset/ip_set_bitmap_port.c112
-rw-r--r--net/netfilter/ipset/ip_set_core.c361
-rw-r--r--net/netfilter/ipset/ip_set_getport.c18
-rw-r--r--net/netfilter/ipset/ip_set_hash_gen.h526
-rw-r--r--net/netfilter/ipset/ip_set_hash_ip.c58
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipport.c80
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportip.c86
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportnet.c108
-rw-r--r--net/netfilter/ipset/ip_set_hash_net.c85
-rw-r--r--net/netfilter/ipset/ip_set_hash_netiface.c98
-rw-r--r--net/netfilter/ipset/ip_set_hash_netnet.c483
-rw-r--r--net/netfilter/ipset/ip_set_hash_netport.c92
-rw-r--r--net/netfilter/ipset/ip_set_hash_netportnet.c588
-rw-r--r--net/netfilter/ipset/ip_set_list_set.c263
-rw-r--r--net/netfilter/nf_conntrack_sip.c133
-rw-r--r--net/netfilter/nf_nat_sip.c35
-rw-r--r--net/netfilter/nfnetlink_cttimeout.c161
-rw-r--r--net/netfilter/nfnetlink_log.c11
-rw-r--r--net/netfilter/nfnetlink_queue_core.c6
-rw-r--r--net/netfilter/xt_TCPMSS.c72
-rw-r--r--net/netfilter/xt_set.c222
-rw-r--r--net/sched/em_ipset.c7
33 files changed, 2677 insertions, 1731 deletions
diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
index 9ac9fbde7b61..7967516adc0d 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -49,31 +49,68 @@ enum ip_set_feature {
49 49
50/* Set extensions */ 50/* Set extensions */
51enum ip_set_extension { 51enum ip_set_extension {
52 IPSET_EXT_NONE = 0, 52 IPSET_EXT_BIT_TIMEOUT = 0,
53 IPSET_EXT_BIT_TIMEOUT = 1,
54 IPSET_EXT_TIMEOUT = (1 << IPSET_EXT_BIT_TIMEOUT), 53 IPSET_EXT_TIMEOUT = (1 << IPSET_EXT_BIT_TIMEOUT),
55 IPSET_EXT_BIT_COUNTER = 2, 54 IPSET_EXT_BIT_COUNTER = 1,
56 IPSET_EXT_COUNTER = (1 << IPSET_EXT_BIT_COUNTER), 55 IPSET_EXT_COUNTER = (1 << IPSET_EXT_BIT_COUNTER),
57}; 56 IPSET_EXT_BIT_COMMENT = 2,
58 57 IPSET_EXT_COMMENT = (1 << IPSET_EXT_BIT_COMMENT),
59/* Extension offsets */ 58 /* Mark set with an extension which needs to call destroy */
60enum ip_set_offset { 59 IPSET_EXT_BIT_DESTROY = 7,
61 IPSET_OFFSET_TIMEOUT = 0, 60 IPSET_EXT_DESTROY = (1 << IPSET_EXT_BIT_DESTROY),
62 IPSET_OFFSET_COUNTER,
63 IPSET_OFFSET_MAX,
64}; 61};
65 62
66#define SET_WITH_TIMEOUT(s) ((s)->extensions & IPSET_EXT_TIMEOUT) 63#define SET_WITH_TIMEOUT(s) ((s)->extensions & IPSET_EXT_TIMEOUT)
67#define SET_WITH_COUNTER(s) ((s)->extensions & IPSET_EXT_COUNTER) 64#define SET_WITH_COUNTER(s) ((s)->extensions & IPSET_EXT_COUNTER)
65#define SET_WITH_COMMENT(s) ((s)->extensions & IPSET_EXT_COMMENT)
66
67/* Extension id, in size order */
68enum ip_set_ext_id {
69 IPSET_EXT_ID_COUNTER = 0,
70 IPSET_EXT_ID_TIMEOUT,
71 IPSET_EXT_ID_COMMENT,
72 IPSET_EXT_ID_MAX,
73};
74
75/* Extension type */
76struct ip_set_ext_type {
77 /* Destroy extension private data (can be NULL) */
78 void (*destroy)(void *ext);
79 enum ip_set_extension type;
80 enum ipset_cadt_flags flag;
81 /* Size and minimal alignment */
82 u8 len;
83 u8 align;
84};
85
86extern const struct ip_set_ext_type ip_set_extensions[];
68 87
69struct ip_set_ext { 88struct ip_set_ext {
70 unsigned long timeout;
71 u64 packets; 89 u64 packets;
72 u64 bytes; 90 u64 bytes;
91 u32 timeout;
92 char *comment;
93};
94
95struct ip_set_counter {
96 atomic64_t bytes;
97 atomic64_t packets;
98};
99
100struct ip_set_comment {
101 char *str;
73}; 102};
74 103
75struct ip_set; 104struct ip_set;
76 105
106#define ext_timeout(e, s) \
107(unsigned long *)(((void *)(e)) + (s)->offset[IPSET_EXT_ID_TIMEOUT])
108#define ext_counter(e, s) \
109(struct ip_set_counter *)(((void *)(e)) + (s)->offset[IPSET_EXT_ID_COUNTER])
110#define ext_comment(e, s) \
111(struct ip_set_comment *)(((void *)(e)) + (s)->offset[IPSET_EXT_ID_COMMENT])
112
113
77typedef int (*ipset_adtfn)(struct ip_set *set, void *value, 114typedef int (*ipset_adtfn)(struct ip_set *set, void *value,
78 const struct ip_set_ext *ext, 115 const struct ip_set_ext *ext,
79 struct ip_set_ext *mext, u32 cmdflags); 116 struct ip_set_ext *mext, u32 cmdflags);
@@ -147,7 +184,8 @@ struct ip_set_type {
147 u8 revision_min, revision_max; 184 u8 revision_min, revision_max;
148 185
149 /* Create set */ 186 /* Create set */
150 int (*create)(struct ip_set *set, struct nlattr *tb[], u32 flags); 187 int (*create)(struct net *net, struct ip_set *set,
188 struct nlattr *tb[], u32 flags);
151 189
152 /* Attribute policies */ 190 /* Attribute policies */
153 const struct nla_policy create_policy[IPSET_ATTR_CREATE_MAX + 1]; 191 const struct nla_policy create_policy[IPSET_ATTR_CREATE_MAX + 1];
@@ -179,14 +217,45 @@ struct ip_set {
179 u8 revision; 217 u8 revision;
180 /* Extensions */ 218 /* Extensions */
181 u8 extensions; 219 u8 extensions;
220 /* Default timeout value, if enabled */
221 u32 timeout;
222 /* Element data size */
223 size_t dsize;
224 /* Offsets to extensions in elements */
225 size_t offset[IPSET_EXT_ID_MAX];
182 /* The type specific data */ 226 /* The type specific data */
183 void *data; 227 void *data;
184}; 228};
185 229
186struct ip_set_counter { 230static inline void
187 atomic64_t bytes; 231ip_set_ext_destroy(struct ip_set *set, void *data)
188 atomic64_t packets; 232{
189}; 233 /* Check that the extension is enabled for the set and
234 * call it's destroy function for its extension part in data.
235 */
236 if (SET_WITH_COMMENT(set))
237 ip_set_extensions[IPSET_EXT_ID_COMMENT].destroy(
238 ext_comment(data, set));
239}
240
241static inline int
242ip_set_put_flags(struct sk_buff *skb, struct ip_set *set)
243{
244 u32 cadt_flags = 0;
245
246 if (SET_WITH_TIMEOUT(set))
247 if (unlikely(nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
248 htonl(set->timeout))))
249 return -EMSGSIZE;
250 if (SET_WITH_COUNTER(set))
251 cadt_flags |= IPSET_FLAG_WITH_COUNTERS;
252 if (SET_WITH_COMMENT(set))
253 cadt_flags |= IPSET_FLAG_WITH_COMMENT;
254
255 if (!cadt_flags)
256 return 0;
257 return nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(cadt_flags));
258}
190 259
191static inline void 260static inline void
192ip_set_add_bytes(u64 bytes, struct ip_set_counter *counter) 261ip_set_add_bytes(u64 bytes, struct ip_set_counter *counter)
@@ -248,12 +317,13 @@ ip_set_init_counter(struct ip_set_counter *counter,
248} 317}
249 318
250/* register and unregister set references */ 319/* register and unregister set references */
251extern ip_set_id_t ip_set_get_byname(const char *name, struct ip_set **set); 320extern ip_set_id_t ip_set_get_byname(struct net *net,
252extern void ip_set_put_byindex(ip_set_id_t index); 321 const char *name, struct ip_set **set);
253extern const char *ip_set_name_byindex(ip_set_id_t index); 322extern void ip_set_put_byindex(struct net *net, ip_set_id_t index);
254extern ip_set_id_t ip_set_nfnl_get(const char *name); 323extern const char *ip_set_name_byindex(struct net *net, ip_set_id_t index);
255extern ip_set_id_t ip_set_nfnl_get_byindex(ip_set_id_t index); 324extern ip_set_id_t ip_set_nfnl_get(struct net *net, const char *name);
256extern void ip_set_nfnl_put(ip_set_id_t index); 325extern ip_set_id_t ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index);
326extern void ip_set_nfnl_put(struct net *net, ip_set_id_t index);
257 327
258/* API for iptables set match, and SET target */ 328/* API for iptables set match, and SET target */
259 329
@@ -272,6 +342,8 @@ extern void *ip_set_alloc(size_t size);
272extern void ip_set_free(void *members); 342extern void ip_set_free(void *members);
273extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr); 343extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr);
274extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr); 344extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr);
345extern size_t ip_set_elem_len(struct ip_set *set, struct nlattr *tb[],
346 size_t len);
275extern int ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[], 347extern int ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
276 struct ip_set_ext *ext); 348 struct ip_set_ext *ext);
277 349
@@ -389,13 +461,40 @@ bitmap_bytes(u32 a, u32 b)
389} 461}
390 462
391#include <linux/netfilter/ipset/ip_set_timeout.h> 463#include <linux/netfilter/ipset/ip_set_timeout.h>
464#include <linux/netfilter/ipset/ip_set_comment.h>
392 465
393#define IP_SET_INIT_KEXT(skb, opt, map) \ 466static inline int
467ip_set_put_extensions(struct sk_buff *skb, const struct ip_set *set,
468 const void *e, bool active)
469{
470 if (SET_WITH_TIMEOUT(set)) {
471 unsigned long *timeout = ext_timeout(e, set);
472
473 if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
474 htonl(active ? ip_set_timeout_get(timeout)
475 : *timeout)))
476 return -EMSGSIZE;
477 }
478 if (SET_WITH_COUNTER(set) &&
479 ip_set_put_counter(skb, ext_counter(e, set)))
480 return -EMSGSIZE;
481 if (SET_WITH_COMMENT(set) &&
482 ip_set_put_comment(skb, ext_comment(e, set)))
483 return -EMSGSIZE;
484 return 0;
485}
486
487#define IP_SET_INIT_KEXT(skb, opt, set) \
394 { .bytes = (skb)->len, .packets = 1, \ 488 { .bytes = (skb)->len, .packets = 1, \
395 .timeout = ip_set_adt_opt_timeout(opt, map) } 489 .timeout = ip_set_adt_opt_timeout(opt, set) }
396 490
397#define IP_SET_INIT_UEXT(map) \ 491#define IP_SET_INIT_UEXT(set) \
398 { .bytes = ULLONG_MAX, .packets = ULLONG_MAX, \ 492 { .bytes = ULLONG_MAX, .packets = ULLONG_MAX, \
399 .timeout = (map)->timeout } 493 .timeout = (set)->timeout }
494
495#define IP_SET_INIT_CIDR(a, b) ((a) ? (a) : (b))
496
497#define IPSET_CONCAT(a, b) a##b
498#define IPSET_TOKEN(a, b) IPSET_CONCAT(a, b)
400 499
401#endif /*_IP_SET_H */ 500#endif /*_IP_SET_H */
diff --git a/include/linux/netfilter/ipset/ip_set_comment.h b/include/linux/netfilter/ipset/ip_set_comment.h
new file mode 100644
index 000000000000..21217ea008d7
--- /dev/null
+++ b/include/linux/netfilter/ipset/ip_set_comment.h
@@ -0,0 +1,57 @@
1#ifndef _IP_SET_COMMENT_H
2#define _IP_SET_COMMENT_H
3
4/* Copyright (C) 2013 Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>
5 *
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
8 * published by the Free Software Foundation.
9 */
10
11#ifdef __KERNEL__
12
13static inline char*
14ip_set_comment_uget(struct nlattr *tb)
15{
16 return nla_data(tb);
17}
18
19static inline void
20ip_set_init_comment(struct ip_set_comment *comment,
21 const struct ip_set_ext *ext)
22{
23 size_t len = ext->comment ? strlen(ext->comment) : 0;
24
25 if (unlikely(comment->str)) {
26 kfree(comment->str);
27 comment->str = NULL;
28 }
29 if (!len)
30 return;
31 if (unlikely(len > IPSET_MAX_COMMENT_SIZE))
32 len = IPSET_MAX_COMMENT_SIZE;
33 comment->str = kzalloc(len + 1, GFP_ATOMIC);
34 if (unlikely(!comment->str))
35 return;
36 strlcpy(comment->str, ext->comment, len + 1);
37}
38
39static inline int
40ip_set_put_comment(struct sk_buff *skb, struct ip_set_comment *comment)
41{
42 if (!comment->str)
43 return 0;
44 return nla_put_string(skb, IPSET_ATTR_COMMENT, comment->str);
45}
46
47static inline void
48ip_set_comment_free(struct ip_set_comment *comment)
49{
50 if (unlikely(!comment->str))
51 return;
52 kfree(comment->str);
53 comment->str = NULL;
54}
55
56#endif
57#endif
diff --git a/include/linux/netfilter/ipset/ip_set_timeout.h b/include/linux/netfilter/ipset/ip_set_timeout.h
index 3aac04167ca7..83c2f9e0886c 100644
--- a/include/linux/netfilter/ipset/ip_set_timeout.h
+++ b/include/linux/netfilter/ipset/ip_set_timeout.h
@@ -23,8 +23,8 @@
23/* Set is defined with timeout support: timeout value may be 0 */ 23/* Set is defined with timeout support: timeout value may be 0 */
24#define IPSET_NO_TIMEOUT UINT_MAX 24#define IPSET_NO_TIMEOUT UINT_MAX
25 25
26#define ip_set_adt_opt_timeout(opt, map) \ 26#define ip_set_adt_opt_timeout(opt, set) \
27((opt)->ext.timeout != IPSET_NO_TIMEOUT ? (opt)->ext.timeout : (map)->timeout) 27((opt)->ext.timeout != IPSET_NO_TIMEOUT ? (opt)->ext.timeout : (set)->timeout)
28 28
29static inline unsigned int 29static inline unsigned int
30ip_set_timeout_uget(struct nlattr *tb) 30ip_set_timeout_uget(struct nlattr *tb)
diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h
index 5cac0207b95d..d5af3c27fb7d 100644
--- a/include/linux/netfilter/nf_conntrack_sip.h
+++ b/include/linux/netfilter/nf_conntrack_sip.h
@@ -107,55 +107,64 @@ enum sdp_header_types {
107 SDP_HDR_MEDIA, 107 SDP_HDR_MEDIA,
108}; 108};
109 109
110extern unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, 110struct nf_nat_sip_hooks {
111 unsigned int protoff, 111 unsigned int (*msg)(struct sk_buff *skb,
112 unsigned int dataoff, 112 unsigned int protoff,
113 const char **dptr, 113 unsigned int dataoff,
114 unsigned int *datalen); 114 const char **dptr,
115extern void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb, 115 unsigned int *datalen);
116 unsigned int protoff, s16 off); 116
117extern unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb, 117 void (*seq_adjust)(struct sk_buff *skb,
118 unsigned int protoff, 118 unsigned int protoff, s16 off);
119 unsigned int dataoff, 119
120 const char **dptr, 120 unsigned int (*expect)(struct sk_buff *skb,
121 unsigned int *datalen, 121 unsigned int protoff,
122 struct nf_conntrack_expect *exp, 122 unsigned int dataoff,
123 unsigned int matchoff, 123 const char **dptr,
124 unsigned int matchlen); 124 unsigned int *datalen,
125extern unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb, 125 struct nf_conntrack_expect *exp,
126 unsigned int protoff, 126 unsigned int matchoff,
127 unsigned int dataoff, 127 unsigned int matchlen);
128 const char **dptr, 128
129 unsigned int *datalen, 129 unsigned int (*sdp_addr)(struct sk_buff *skb,
130 unsigned int sdpoff, 130 unsigned int protoff,
131 enum sdp_header_types type, 131 unsigned int dataoff,
132 enum sdp_header_types term, 132 const char **dptr,
133 const union nf_inet_addr *addr); 133 unsigned int *datalen,
134extern unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb, 134 unsigned int sdpoff,
135 unsigned int protoff, 135 enum sdp_header_types type,
136 unsigned int dataoff, 136 enum sdp_header_types term,
137 const char **dptr, 137 const union nf_inet_addr *addr);
138 unsigned int *datalen, 138
139 unsigned int matchoff, 139 unsigned int (*sdp_port)(struct sk_buff *skb,
140 unsigned int matchlen, 140 unsigned int protoff,
141 u_int16_t port); 141 unsigned int dataoff,
142extern unsigned int (*nf_nat_sdp_session_hook)(struct sk_buff *skb, 142 const char **dptr,
143 unsigned int protoff, 143 unsigned int *datalen,
144 unsigned int dataoff, 144 unsigned int matchoff,
145 const char **dptr, 145 unsigned int matchlen,
146 unsigned int *datalen, 146 u_int16_t port);
147 unsigned int sdpoff, 147
148 const union nf_inet_addr *addr); 148 unsigned int (*sdp_session)(struct sk_buff *skb,
149extern unsigned int (*nf_nat_sdp_media_hook)(struct sk_buff *skb, 149 unsigned int protoff,
150 unsigned int protoff, 150 unsigned int dataoff,
151 unsigned int dataoff, 151 const char **dptr,
152 const char **dptr, 152 unsigned int *datalen,
153 unsigned int *datalen, 153 unsigned int sdpoff,
154 struct nf_conntrack_expect *rtp_exp, 154 const union nf_inet_addr *addr);
155 struct nf_conntrack_expect *rtcp_exp, 155
156 unsigned int mediaoff, 156 unsigned int (*sdp_media)(struct sk_buff *skb,
157 unsigned int medialen, 157 unsigned int protoff,
158 union nf_inet_addr *rtp_addr); 158 unsigned int dataoff,
159 const char **dptr,
160 unsigned int *datalen,
161 struct nf_conntrack_expect *rtp_exp,
162 struct nf_conntrack_expect *rtcp_exp,
163 unsigned int mediaoff,
164 unsigned int medialen,
165 union nf_inet_addr *rtp_addr);
166};
167extern const struct nf_nat_sip_hooks *nf_nat_sip_hooks;
159 168
160int ct_sip_parse_request(const struct nf_conn *ct, const char *dptr, 169int ct_sip_parse_request(const struct nf_conn *ct, const char *dptr,
161 unsigned int datalen, unsigned int *matchoff, 170 unsigned int datalen, unsigned int *matchoff,
diff --git a/include/uapi/linux/netfilter/ipset/ip_set.h b/include/uapi/linux/netfilter/ipset/ip_set.h
index 8024cdf13b70..25d3b2f79c02 100644
--- a/include/uapi/linux/netfilter/ipset/ip_set.h
+++ b/include/uapi/linux/netfilter/ipset/ip_set.h
@@ -10,12 +10,14 @@
10#ifndef _UAPI_IP_SET_H 10#ifndef _UAPI_IP_SET_H
11#define _UAPI_IP_SET_H 11#define _UAPI_IP_SET_H
12 12
13
14#include <linux/types.h> 13#include <linux/types.h>
15 14
16/* The protocol version */ 15/* The protocol version */
17#define IPSET_PROTOCOL 6 16#define IPSET_PROTOCOL 6
18 17
18/* The maximum permissible comment length we will accept over netlink */
19#define IPSET_MAX_COMMENT_SIZE 255
20
19/* The max length of strings including NUL: set and type identifiers */ 21/* The max length of strings including NUL: set and type identifiers */
20#define IPSET_MAXNAMELEN 32 22#define IPSET_MAXNAMELEN 32
21 23
@@ -110,6 +112,7 @@ enum {
110 IPSET_ATTR_IFACE, 112 IPSET_ATTR_IFACE,
111 IPSET_ATTR_BYTES, 113 IPSET_ATTR_BYTES,
112 IPSET_ATTR_PACKETS, 114 IPSET_ATTR_PACKETS,
115 IPSET_ATTR_COMMENT,
113 __IPSET_ATTR_ADT_MAX, 116 __IPSET_ATTR_ADT_MAX,
114}; 117};
115#define IPSET_ATTR_ADT_MAX (__IPSET_ATTR_ADT_MAX - 1) 118#define IPSET_ATTR_ADT_MAX (__IPSET_ATTR_ADT_MAX - 1)
@@ -140,6 +143,7 @@ enum ipset_errno {
140 IPSET_ERR_IPADDR_IPV4, 143 IPSET_ERR_IPADDR_IPV4,
141 IPSET_ERR_IPADDR_IPV6, 144 IPSET_ERR_IPADDR_IPV6,
142 IPSET_ERR_COUNTER, 145 IPSET_ERR_COUNTER,
146 IPSET_ERR_COMMENT,
143 147
144 /* Type specific error codes */ 148 /* Type specific error codes */
145 IPSET_ERR_TYPE_SPECIFIC = 4352, 149 IPSET_ERR_TYPE_SPECIFIC = 4352,
@@ -176,6 +180,8 @@ enum ipset_cadt_flags {
176 IPSET_FLAG_NOMATCH = (1 << IPSET_FLAG_BIT_NOMATCH), 180 IPSET_FLAG_NOMATCH = (1 << IPSET_FLAG_BIT_NOMATCH),
177 IPSET_FLAG_BIT_WITH_COUNTERS = 3, 181 IPSET_FLAG_BIT_WITH_COUNTERS = 3,
178 IPSET_FLAG_WITH_COUNTERS = (1 << IPSET_FLAG_BIT_WITH_COUNTERS), 182 IPSET_FLAG_WITH_COUNTERS = (1 << IPSET_FLAG_BIT_WITH_COUNTERS),
183 IPSET_FLAG_BIT_WITH_COMMENT = 4,
184 IPSET_FLAG_WITH_COMMENT = (1 << IPSET_FLAG_BIT_WITH_COMMENT),
179 IPSET_FLAG_CADT_MAX = 15, 185 IPSET_FLAG_CADT_MAX = 15,
180}; 186};
181 187
@@ -250,6 +256,14 @@ struct ip_set_req_get_set {
250#define IP_SET_OP_GET_BYINDEX 0x00000007 /* Get set name by index */ 256#define IP_SET_OP_GET_BYINDEX 0x00000007 /* Get set name by index */
251/* Uses ip_set_req_get_set */ 257/* Uses ip_set_req_get_set */
252 258
259#define IP_SET_OP_GET_FNAME 0x00000008 /* Get set index and family */
260struct ip_set_req_get_set_family {
261 unsigned int op;
262 unsigned int version;
263 unsigned int family;
264 union ip_set_name_index set;
265};
266
253#define IP_SET_OP_VERSION 0x00000100 /* Ask kernel version */ 267#define IP_SET_OP_VERSION 0x00000100 /* Ask kernel version */
254struct ip_set_req_version { 268struct ip_set_req_version {
255 unsigned int op; 269 unsigned int op;
diff --git a/include/uapi/linux/netfilter/nfnetlink_cttimeout.h b/include/uapi/linux/netfilter/nfnetlink_cttimeout.h
index a2810a7c5e30..1ab0b97b3a1e 100644
--- a/include/uapi/linux/netfilter/nfnetlink_cttimeout.h
+++ b/include/uapi/linux/netfilter/nfnetlink_cttimeout.h
@@ -6,6 +6,8 @@ enum ctnl_timeout_msg_types {
6 IPCTNL_MSG_TIMEOUT_NEW, 6 IPCTNL_MSG_TIMEOUT_NEW,
7 IPCTNL_MSG_TIMEOUT_GET, 7 IPCTNL_MSG_TIMEOUT_GET,
8 IPCTNL_MSG_TIMEOUT_DELETE, 8 IPCTNL_MSG_TIMEOUT_DELETE,
9 IPCTNL_MSG_TIMEOUT_DEFAULT_SET,
10 IPCTNL_MSG_TIMEOUT_DEFAULT_GET,
9 11
10 IPCTNL_MSG_TIMEOUT_MAX 12 IPCTNL_MSG_TIMEOUT_MAX
11}; 13};
diff --git a/net/netfilter/ipset/Kconfig b/net/netfilter/ipset/Kconfig
index ba36c283d837..a2d6263b6c64 100644
--- a/net/netfilter/ipset/Kconfig
+++ b/net/netfilter/ipset/Kconfig
@@ -1,7 +1,7 @@
1menuconfig IP_SET 1menuconfig IP_SET
2 tristate "IP set support" 2 tristate "IP set support"
3 depends on INET && NETFILTER 3 depends on INET && NETFILTER
4 depends on NETFILTER_NETLINK 4 select NETFILTER_NETLINK
5 help 5 help
6 This option adds IP set support to the kernel. 6 This option adds IP set support to the kernel.
7 In order to define and use the sets, you need the userspace utility 7 In order to define and use the sets, you need the userspace utility
@@ -90,6 +90,15 @@ config IP_SET_HASH_IPPORTNET
90 90
91 To compile it as a module, choose M here. If unsure, say N. 91 To compile it as a module, choose M here. If unsure, say N.
92 92
93config IP_SET_HASH_NETPORTNET
94 tristate "hash:net,port,net set support"
95 depends on IP_SET
96 help
97 This option adds the hash:net,port,net set type support, by which
98 one can store two IPv4/IPv6 subnets, and a protocol/port in a set.
99
100 To compile it as a module, choose M here. If unsure, say N.
101
93config IP_SET_HASH_NET 102config IP_SET_HASH_NET
94 tristate "hash:net set support" 103 tristate "hash:net set support"
95 depends on IP_SET 104 depends on IP_SET
@@ -99,6 +108,15 @@ config IP_SET_HASH_NET
99 108
100 To compile it as a module, choose M here. If unsure, say N. 109 To compile it as a module, choose M here. If unsure, say N.
101 110
111config IP_SET_HASH_NETNET
112 tristate "hash:net,net set support"
113 depends on IP_SET
114 help
115 This option adds the hash:net,net set type support, by which
116 one can store IPv4/IPv6 network address/prefix pairs in a set.
117
118 To compile it as a module, choose M here. If unsure, say N.
119
102config IP_SET_HASH_NETPORT 120config IP_SET_HASH_NETPORT
103 tristate "hash:net,port set support" 121 tristate "hash:net,port set support"
104 depends on IP_SET 122 depends on IP_SET
diff --git a/net/netfilter/ipset/Makefile b/net/netfilter/ipset/Makefile
index 6e965ecd5444..44b2d38476fa 100644
--- a/net/netfilter/ipset/Makefile
+++ b/net/netfilter/ipset/Makefile
@@ -20,6 +20,8 @@ obj-$(CONFIG_IP_SET_HASH_IPPORTNET) += ip_set_hash_ipportnet.o
20obj-$(CONFIG_IP_SET_HASH_NET) += ip_set_hash_net.o 20obj-$(CONFIG_IP_SET_HASH_NET) += ip_set_hash_net.o
21obj-$(CONFIG_IP_SET_HASH_NETPORT) += ip_set_hash_netport.o 21obj-$(CONFIG_IP_SET_HASH_NETPORT) += ip_set_hash_netport.o
22obj-$(CONFIG_IP_SET_HASH_NETIFACE) += ip_set_hash_netiface.o 22obj-$(CONFIG_IP_SET_HASH_NETIFACE) += ip_set_hash_netiface.o
23obj-$(CONFIG_IP_SET_HASH_NETNET) += ip_set_hash_netnet.o
24obj-$(CONFIG_IP_SET_HASH_NETPORTNET) += ip_set_hash_netportnet.o
23 25
24# list types 26# list types
25obj-$(CONFIG_IP_SET_LIST_SET) += ip_set_list_set.o 27obj-$(CONFIG_IP_SET_LIST_SET) += ip_set_list_set.o
diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h b/net/netfilter/ipset/ip_set_bitmap_gen.h
index 25243379b887..a13e15be7911 100644
--- a/net/netfilter/ipset/ip_set_bitmap_gen.h
+++ b/net/netfilter/ipset/ip_set_bitmap_gen.h
@@ -8,38 +8,32 @@
8#ifndef __IP_SET_BITMAP_IP_GEN_H 8#ifndef __IP_SET_BITMAP_IP_GEN_H
9#define __IP_SET_BITMAP_IP_GEN_H 9#define __IP_SET_BITMAP_IP_GEN_H
10 10
11#define CONCAT(a, b) a##b 11#define mtype_do_test IPSET_TOKEN(MTYPE, _do_test)
12#define TOKEN(a,b) CONCAT(a, b) 12#define mtype_gc_test IPSET_TOKEN(MTYPE, _gc_test)
13 13#define mtype_is_filled IPSET_TOKEN(MTYPE, _is_filled)
14#define mtype_do_test TOKEN(MTYPE, _do_test) 14#define mtype_do_add IPSET_TOKEN(MTYPE, _do_add)
15#define mtype_gc_test TOKEN(MTYPE, _gc_test) 15#define mtype_ext_cleanup IPSET_TOKEN(MTYPE, _ext_cleanup)
16#define mtype_is_filled TOKEN(MTYPE, _is_filled) 16#define mtype_do_del IPSET_TOKEN(MTYPE, _do_del)
17#define mtype_do_add TOKEN(MTYPE, _do_add) 17#define mtype_do_list IPSET_TOKEN(MTYPE, _do_list)
18#define mtype_do_del TOKEN(MTYPE, _do_del) 18#define mtype_do_head IPSET_TOKEN(MTYPE, _do_head)
19#define mtype_do_list TOKEN(MTYPE, _do_list) 19#define mtype_adt_elem IPSET_TOKEN(MTYPE, _adt_elem)
20#define mtype_do_head TOKEN(MTYPE, _do_head) 20#define mtype_add_timeout IPSET_TOKEN(MTYPE, _add_timeout)
21#define mtype_adt_elem TOKEN(MTYPE, _adt_elem) 21#define mtype_gc_init IPSET_TOKEN(MTYPE, _gc_init)
22#define mtype_add_timeout TOKEN(MTYPE, _add_timeout) 22#define mtype_kadt IPSET_TOKEN(MTYPE, _kadt)
23#define mtype_gc_init TOKEN(MTYPE, _gc_init) 23#define mtype_uadt IPSET_TOKEN(MTYPE, _uadt)
24#define mtype_kadt TOKEN(MTYPE, _kadt) 24#define mtype_destroy IPSET_TOKEN(MTYPE, _destroy)
25#define mtype_uadt TOKEN(MTYPE, _uadt) 25#define mtype_flush IPSET_TOKEN(MTYPE, _flush)
26#define mtype_destroy TOKEN(MTYPE, _destroy) 26#define mtype_head IPSET_TOKEN(MTYPE, _head)
27#define mtype_flush TOKEN(MTYPE, _flush) 27#define mtype_same_set IPSET_TOKEN(MTYPE, _same_set)
28#define mtype_head TOKEN(MTYPE, _head) 28#define mtype_elem IPSET_TOKEN(MTYPE, _elem)
29#define mtype_same_set TOKEN(MTYPE, _same_set) 29#define mtype_test IPSET_TOKEN(MTYPE, _test)
30#define mtype_elem TOKEN(MTYPE, _elem) 30#define mtype_add IPSET_TOKEN(MTYPE, _add)
31#define mtype_test TOKEN(MTYPE, _test) 31#define mtype_del IPSET_TOKEN(MTYPE, _del)
32#define mtype_add TOKEN(MTYPE, _add) 32#define mtype_list IPSET_TOKEN(MTYPE, _list)
33#define mtype_del TOKEN(MTYPE, _del) 33#define mtype_gc IPSET_TOKEN(MTYPE, _gc)
34#define mtype_list TOKEN(MTYPE, _list)
35#define mtype_gc TOKEN(MTYPE, _gc)
36#define mtype MTYPE 34#define mtype MTYPE
37 35
38#define ext_timeout(e, m) \ 36#define get_ext(set, map, id) ((map)->extensions + (set)->dsize * (id))
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 37
44static void 38static void
45mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set)) 39mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
@@ -49,11 +43,22 @@ mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
49 init_timer(&map->gc); 43 init_timer(&map->gc);
50 map->gc.data = (unsigned long) set; 44 map->gc.data = (unsigned long) set;
51 map->gc.function = gc; 45 map->gc.function = gc;
52 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; 46 map->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
53 add_timer(&map->gc); 47 add_timer(&map->gc);
54} 48}
55 49
56static void 50static void
51mtype_ext_cleanup(struct ip_set *set)
52{
53 struct mtype *map = set->data;
54 u32 id;
55
56 for (id = 0; id < map->elements; id++)
57 if (test_bit(id, map->members))
58 ip_set_ext_destroy(set, get_ext(set, map, id));
59}
60
61static void
57mtype_destroy(struct ip_set *set) 62mtype_destroy(struct ip_set *set)
58{ 63{
59 struct mtype *map = set->data; 64 struct mtype *map = set->data;
@@ -62,8 +67,11 @@ mtype_destroy(struct ip_set *set)
62 del_timer_sync(&map->gc); 67 del_timer_sync(&map->gc);
63 68
64 ip_set_free(map->members); 69 ip_set_free(map->members);
65 if (map->dsize) 70 if (set->dsize) {
71 if (set->extensions & IPSET_EXT_DESTROY)
72 mtype_ext_cleanup(set);
66 ip_set_free(map->extensions); 73 ip_set_free(map->extensions);
74 }
67 kfree(map); 75 kfree(map);
68 76
69 set->data = NULL; 77 set->data = NULL;
@@ -74,6 +82,8 @@ mtype_flush(struct ip_set *set)
74{ 82{
75 struct mtype *map = set->data; 83 struct mtype *map = set->data;
76 84
85 if (set->extensions & IPSET_EXT_DESTROY)
86 mtype_ext_cleanup(set);
77 memset(map->members, 0, map->memsize); 87 memset(map->members, 0, map->memsize);
78} 88}
79 89
@@ -91,12 +101,9 @@ mtype_head(struct ip_set *set, struct sk_buff *skb)
91 nla_put_net32(skb, IPSET_ATTR_MEMSIZE, 101 nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
92 htonl(sizeof(*map) + 102 htonl(sizeof(*map) +
93 map->memsize + 103 map->memsize +
94 map->dsize * map->elements)) || 104 set->dsize * map->elements)))
95 (SET_WITH_TIMEOUT(set) && 105 goto nla_put_failure;
96 nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))) || 106 if (unlikely(ip_set_put_flags(skb, set)))
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; 107 goto nla_put_failure;
101 ipset_nest_end(skb, nested); 108 ipset_nest_end(skb, nested);
102 109
@@ -111,16 +118,16 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext,
111{ 118{
112 struct mtype *map = set->data; 119 struct mtype *map = set->data;
113 const struct mtype_adt_elem *e = value; 120 const struct mtype_adt_elem *e = value;
114 void *x = get_ext(map, e->id); 121 void *x = get_ext(set, map, e->id);
115 int ret = mtype_do_test(e, map); 122 int ret = mtype_do_test(e, map, set->dsize);
116 123
117 if (ret <= 0) 124 if (ret <= 0)
118 return ret; 125 return ret;
119 if (SET_WITH_TIMEOUT(set) && 126 if (SET_WITH_TIMEOUT(set) &&
120 ip_set_timeout_expired(ext_timeout(x, map))) 127 ip_set_timeout_expired(ext_timeout(x, set)))
121 return 0; 128 return 0;
122 if (SET_WITH_COUNTER(set)) 129 if (SET_WITH_COUNTER(set))
123 ip_set_update_counter(ext_counter(x, map), ext, mext, flags); 130 ip_set_update_counter(ext_counter(x, set), ext, mext, flags);
124 return 1; 131 return 1;
125} 132}
126 133
@@ -130,26 +137,30 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
130{ 137{
131 struct mtype *map = set->data; 138 struct mtype *map = set->data;
132 const struct mtype_adt_elem *e = value; 139 const struct mtype_adt_elem *e = value;
133 void *x = get_ext(map, e->id); 140 void *x = get_ext(set, map, e->id);
134 int ret = mtype_do_add(e, map, flags); 141 int ret = mtype_do_add(e, map, flags, set->dsize);
135 142
136 if (ret == IPSET_ADD_FAILED) { 143 if (ret == IPSET_ADD_FAILED) {
137 if (SET_WITH_TIMEOUT(set) && 144 if (SET_WITH_TIMEOUT(set) &&
138 ip_set_timeout_expired(ext_timeout(x, map))) 145 ip_set_timeout_expired(ext_timeout(x, set)))
139 ret = 0; 146 ret = 0;
140 else if (!(flags & IPSET_FLAG_EXIST)) 147 else if (!(flags & IPSET_FLAG_EXIST))
141 return -IPSET_ERR_EXIST; 148 return -IPSET_ERR_EXIST;
149 /* Element is re-added, cleanup extensions */
150 ip_set_ext_destroy(set, x);
142 } 151 }
143 152
144 if (SET_WITH_TIMEOUT(set)) 153 if (SET_WITH_TIMEOUT(set))
145#ifdef IP_SET_BITMAP_STORED_TIMEOUT 154#ifdef IP_SET_BITMAP_STORED_TIMEOUT
146 mtype_add_timeout(ext_timeout(x, map), e, ext, map, ret); 155 mtype_add_timeout(ext_timeout(x, set), e, ext, set, map, ret);
147#else 156#else
148 ip_set_timeout_set(ext_timeout(x, map), ext->timeout); 157 ip_set_timeout_set(ext_timeout(x, set), ext->timeout);
149#endif 158#endif
150 159
151 if (SET_WITH_COUNTER(set)) 160 if (SET_WITH_COUNTER(set))
152 ip_set_init_counter(ext_counter(x, map), ext); 161 ip_set_init_counter(ext_counter(x, set), ext);
162 if (SET_WITH_COMMENT(set))
163 ip_set_init_comment(ext_comment(x, set), ext);
153 return 0; 164 return 0;
154} 165}
155 166
@@ -159,16 +170,27 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext,
159{ 170{
160 struct mtype *map = set->data; 171 struct mtype *map = set->data;
161 const struct mtype_adt_elem *e = value; 172 const struct mtype_adt_elem *e = value;
162 const void *x = get_ext(map, e->id); 173 void *x = get_ext(set, map, e->id);
163 174
164 if (mtype_do_del(e, map) || 175 if (mtype_do_del(e, map))
165 (SET_WITH_TIMEOUT(set) && 176 return -IPSET_ERR_EXIST;
166 ip_set_timeout_expired(ext_timeout(x, map)))) 177
178 ip_set_ext_destroy(set, x);
179 if (SET_WITH_TIMEOUT(set) &&
180 ip_set_timeout_expired(ext_timeout(x, set)))
167 return -IPSET_ERR_EXIST; 181 return -IPSET_ERR_EXIST;
168 182
169 return 0; 183 return 0;
170} 184}
171 185
186#ifndef IP_SET_BITMAP_STORED_TIMEOUT
187static inline bool
188mtype_is_filled(const struct mtype_elem *x)
189{
190 return true;
191}
192#endif
193
172static int 194static int
173mtype_list(const struct ip_set *set, 195mtype_list(const struct ip_set *set,
174 struct sk_buff *skb, struct netlink_callback *cb) 196 struct sk_buff *skb, struct netlink_callback *cb)
@@ -183,13 +205,13 @@ mtype_list(const struct ip_set *set,
183 return -EMSGSIZE; 205 return -EMSGSIZE;
184 for (; cb->args[2] < map->elements; cb->args[2]++) { 206 for (; cb->args[2] < map->elements; cb->args[2]++) {
185 id = cb->args[2]; 207 id = cb->args[2];
186 x = get_ext(map, id); 208 x = get_ext(set, map, id);
187 if (!test_bit(id, map->members) || 209 if (!test_bit(id, map->members) ||
188 (SET_WITH_TIMEOUT(set) && 210 (SET_WITH_TIMEOUT(set) &&
189#ifdef IP_SET_BITMAP_STORED_TIMEOUT 211#ifdef IP_SET_BITMAP_STORED_TIMEOUT
190 mtype_is_filled((const struct mtype_elem *) x) && 212 mtype_is_filled((const struct mtype_elem *) x) &&
191#endif 213#endif
192 ip_set_timeout_expired(ext_timeout(x, map)))) 214 ip_set_timeout_expired(ext_timeout(x, set))))
193 continue; 215 continue;
194 nested = ipset_nest_start(skb, IPSET_ATTR_DATA); 216 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
195 if (!nested) { 217 if (!nested) {
@@ -199,23 +221,10 @@ mtype_list(const struct ip_set *set,
199 } else 221 } else
200 goto nla_put_failure; 222 goto nla_put_failure;
201 } 223 }
202 if (mtype_do_list(skb, map, id)) 224 if (mtype_do_list(skb, map, id, set->dsize))
203 goto nla_put_failure; 225 goto nla_put_failure;
204 if (SET_WITH_TIMEOUT(set)) { 226 if (ip_set_put_extensions(skb, set, x,
205#ifdef IP_SET_BITMAP_STORED_TIMEOUT 227 mtype_is_filled((const struct mtype_elem *) x)))
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; 228 goto nla_put_failure;
220 ipset_nest_end(skb, nested); 229 ipset_nest_end(skb, nested);
221 } 230 }
@@ -228,11 +237,11 @@ mtype_list(const struct ip_set *set,
228 237
229nla_put_failure: 238nla_put_failure:
230 nla_nest_cancel(skb, nested); 239 nla_nest_cancel(skb, nested);
231 ipset_nest_end(skb, adt);
232 if (unlikely(id == first)) { 240 if (unlikely(id == first)) {
233 cb->args[2] = 0; 241 cb->args[2] = 0;
234 return -EMSGSIZE; 242 return -EMSGSIZE;
235 } 243 }
244 ipset_nest_end(skb, adt);
236 return 0; 245 return 0;
237} 246}
238 247
@@ -241,21 +250,23 @@ mtype_gc(unsigned long ul_set)
241{ 250{
242 struct ip_set *set = (struct ip_set *) ul_set; 251 struct ip_set *set = (struct ip_set *) ul_set;
243 struct mtype *map = set->data; 252 struct mtype *map = set->data;
244 const void *x; 253 void *x;
245 u32 id; 254 u32 id;
246 255
247 /* We run parallel with other readers (test element) 256 /* We run parallel with other readers (test element)
248 * but adding/deleting new entries is locked out */ 257 * but adding/deleting new entries is locked out */
249 read_lock_bh(&set->lock); 258 read_lock_bh(&set->lock);
250 for (id = 0; id < map->elements; id++) 259 for (id = 0; id < map->elements; id++)
251 if (mtype_gc_test(id, map)) { 260 if (mtype_gc_test(id, map, set->dsize)) {
252 x = get_ext(map, id); 261 x = get_ext(set, map, id);
253 if (ip_set_timeout_expired(ext_timeout(x, map))) 262 if (ip_set_timeout_expired(ext_timeout(x, set))) {
254 clear_bit(id, map->members); 263 clear_bit(id, map->members);
264 ip_set_ext_destroy(set, x);
265 }
255 } 266 }
256 read_unlock_bh(&set->lock); 267 read_unlock_bh(&set->lock);
257 268
258 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; 269 map->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
259 add_timer(&map->gc); 270 add_timer(&map->gc);
260} 271}
261 272
diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c
index f1a8128bef01..6f1f9f494808 100644
--- a/net/netfilter/ipset/ip_set_bitmap_ip.c
+++ b/net/netfilter/ipset/ip_set_bitmap_ip.c
@@ -25,12 +25,13 @@
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 27
28#define REVISION_MIN 0 28#define IPSET_TYPE_REV_MIN 0
29#define REVISION_MAX 1 /* Counter support added */ 29/* 1 Counter support added */
30#define IPSET_TYPE_REV_MAX 2 /* Comment support added */
30 31
31MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 33MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
33IP_SET_MODULE_DESC("bitmap:ip", REVISION_MIN, REVISION_MAX); 34IP_SET_MODULE_DESC("bitmap:ip", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
34MODULE_ALIAS("ip_set_bitmap:ip"); 35MODULE_ALIAS("ip_set_bitmap:ip");
35 36
36#define MTYPE bitmap_ip 37#define MTYPE bitmap_ip
@@ -44,10 +45,7 @@ struct bitmap_ip {
44 u32 elements; /* number of max elements in the set */ 45 u32 elements; /* number of max elements in the set */
45 u32 hosts; /* number of hosts in a subnet */ 46 u32 hosts; /* number of hosts in a subnet */
46 size_t memsize; /* members size */ 47 size_t memsize; /* members size */
47 size_t dsize; /* extensions struct size */
48 size_t offset[IPSET_OFFSET_MAX]; /* Offsets to extensions */
49 u8 netmask; /* subnet netmask */ 48 u8 netmask; /* subnet netmask */
50 u32 timeout; /* timeout parameter */
51 struct timer_list gc; /* garbage collection */ 49 struct timer_list gc; /* garbage collection */
52}; 50};
53 51
@@ -65,20 +63,21 @@ ip_to_id(const struct bitmap_ip *m, u32 ip)
65/* Common functions */ 63/* Common functions */
66 64
67static inline int 65static inline int
68bitmap_ip_do_test(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map) 66bitmap_ip_do_test(const struct bitmap_ip_adt_elem *e,
67 struct bitmap_ip *map, size_t dsize)
69{ 68{
70 return !!test_bit(e->id, map->members); 69 return !!test_bit(e->id, map->members);
71} 70}
72 71
73static inline int 72static inline int
74bitmap_ip_gc_test(u16 id, const struct bitmap_ip *map) 73bitmap_ip_gc_test(u16 id, const struct bitmap_ip *map, size_t dsize)
75{ 74{
76 return !!test_bit(id, map->members); 75 return !!test_bit(id, map->members);
77} 76}
78 77
79static inline int 78static inline int
80bitmap_ip_do_add(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map, 79bitmap_ip_do_add(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map,
81 u32 flags) 80 u32 flags, size_t dsize)
82{ 81{
83 return !!test_and_set_bit(e->id, map->members); 82 return !!test_and_set_bit(e->id, map->members);
84} 83}
@@ -90,7 +89,8 @@ bitmap_ip_do_del(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map)
90} 89}
91 90
92static inline int 91static inline int
93bitmap_ip_do_list(struct sk_buff *skb, const struct bitmap_ip *map, u32 id) 92bitmap_ip_do_list(struct sk_buff *skb, const struct bitmap_ip *map, u32 id,
93 size_t dsize)
94{ 94{
95 return nla_put_ipaddr4(skb, IPSET_ATTR_IP, 95 return nla_put_ipaddr4(skb, IPSET_ATTR_IP,
96 htonl(map->first_ip + id * map->hosts)); 96 htonl(map->first_ip + id * map->hosts));
@@ -113,7 +113,7 @@ bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb,
113 struct bitmap_ip *map = set->data; 113 struct bitmap_ip *map = set->data;
114 ipset_adtfn adtfn = set->variant->adt[adt]; 114 ipset_adtfn adtfn = set->variant->adt[adt];
115 struct bitmap_ip_adt_elem e = { }; 115 struct bitmap_ip_adt_elem e = { };
116 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map); 116 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
117 u32 ip; 117 u32 ip;
118 118
119 ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC)); 119 ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
@@ -131,9 +131,9 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
131{ 131{
132 struct bitmap_ip *map = set->data; 132 struct bitmap_ip *map = set->data;
133 ipset_adtfn adtfn = set->variant->adt[adt]; 133 ipset_adtfn adtfn = set->variant->adt[adt];
134 u32 ip, ip_to; 134 u32 ip = 0, ip_to = 0;
135 struct bitmap_ip_adt_elem e = { }; 135 struct bitmap_ip_adt_elem e = { };
136 struct ip_set_ext ext = IP_SET_INIT_UEXT(map); 136 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
137 int ret = 0; 137 int ret = 0;
138 138
139 if (unlikely(!tb[IPSET_ATTR_IP] || 139 if (unlikely(!tb[IPSET_ATTR_IP] ||
@@ -200,7 +200,7 @@ bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b)
200 return x->first_ip == y->first_ip && 200 return x->first_ip == y->first_ip &&
201 x->last_ip == y->last_ip && 201 x->last_ip == y->last_ip &&
202 x->netmask == y->netmask && 202 x->netmask == y->netmask &&
203 x->timeout == y->timeout && 203 a->timeout == b->timeout &&
204 a->extensions == b->extensions; 204 a->extensions == b->extensions;
205} 205}
206 206
@@ -209,25 +209,6 @@ bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b)
209struct bitmap_ip_elem { 209struct bitmap_ip_elem {
210}; 210};
211 211
212/* Timeout variant */
213
214struct bitmap_ipt_elem {
215 unsigned long timeout;
216};
217
218/* Plain variant with counter */
219
220struct bitmap_ipc_elem {
221 struct ip_set_counter counter;
222};
223
224/* Timeout variant with counter */
225
226struct bitmap_ipct_elem {
227 unsigned long timeout;
228 struct ip_set_counter counter;
229};
230
231#include "ip_set_bitmap_gen.h" 212#include "ip_set_bitmap_gen.h"
232 213
233/* Create bitmap:ip type of sets */ 214/* Create bitmap:ip type of sets */
@@ -240,8 +221,8 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map,
240 map->members = ip_set_alloc(map->memsize); 221 map->members = ip_set_alloc(map->memsize);
241 if (!map->members) 222 if (!map->members)
242 return false; 223 return false;
243 if (map->dsize) { 224 if (set->dsize) {
244 map->extensions = ip_set_alloc(map->dsize * elements); 225 map->extensions = ip_set_alloc(set->dsize * elements);
245 if (!map->extensions) { 226 if (!map->extensions) {
246 kfree(map->members); 227 kfree(map->members);
247 return false; 228 return false;
@@ -252,7 +233,7 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map,
252 map->elements = elements; 233 map->elements = elements;
253 map->hosts = hosts; 234 map->hosts = hosts;
254 map->netmask = netmask; 235 map->netmask = netmask;
255 map->timeout = IPSET_NO_TIMEOUT; 236 set->timeout = IPSET_NO_TIMEOUT;
256 237
257 set->data = map; 238 set->data = map;
258 set->family = NFPROTO_IPV4; 239 set->family = NFPROTO_IPV4;
@@ -261,10 +242,11 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map,
261} 242}
262 243
263static int 244static int
264bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) 245bitmap_ip_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
246 u32 flags)
265{ 247{
266 struct bitmap_ip *map; 248 struct bitmap_ip *map;
267 u32 first_ip, last_ip, hosts, cadt_flags = 0; 249 u32 first_ip = 0, last_ip = 0, hosts;
268 u64 elements; 250 u64 elements;
269 u8 netmask = 32; 251 u8 netmask = 32;
270 int ret; 252 int ret;
@@ -336,61 +318,15 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
336 318
337 map->memsize = bitmap_bytes(0, elements - 1); 319 map->memsize = bitmap_bytes(0, elements - 1);
338 set->variant = &bitmap_ip; 320 set->variant = &bitmap_ip;
339 if (tb[IPSET_ATTR_CADT_FLAGS]) 321 set->dsize = ip_set_elem_len(set, tb, 0);
340 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 322 if (!init_map_ip(set, map, first_ip, last_ip,
341 if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) { 323 elements, hosts, netmask)) {
342 set->extensions |= IPSET_EXT_COUNTER; 324 kfree(map);
343 if (tb[IPSET_ATTR_TIMEOUT]) { 325 return -ENOMEM;
344 map->dsize = sizeof(struct bitmap_ipct_elem); 326 }
345 map->offset[IPSET_OFFSET_TIMEOUT] = 327 if (tb[IPSET_ATTR_TIMEOUT]) {
346 offsetof(struct bitmap_ipct_elem, timeout); 328 set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_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);
376
377 if (!init_map_ip(set, map, first_ip, last_ip,
378 elements, hosts, netmask)) {
379 kfree(map);
380 return -ENOMEM;
381 }
382
383 map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
384 set->extensions |= IPSET_EXT_TIMEOUT;
385
386 bitmap_ip_gc_init(set, bitmap_ip_gc); 329 bitmap_ip_gc_init(set, bitmap_ip_gc);
387 } else {
388 map->dsize = 0;
389 if (!init_map_ip(set, map, first_ip, last_ip,
390 elements, hosts, netmask)) {
391 kfree(map);
392 return -ENOMEM;
393 }
394 } 330 }
395 return 0; 331 return 0;
396} 332}
@@ -401,8 +337,8 @@ static struct ip_set_type bitmap_ip_type __read_mostly = {
401 .features = IPSET_TYPE_IP, 337 .features = IPSET_TYPE_IP,
402 .dimension = IPSET_DIM_ONE, 338 .dimension = IPSET_DIM_ONE,
403 .family = NFPROTO_IPV4, 339 .family = NFPROTO_IPV4,
404 .revision_min = REVISION_MIN, 340 .revision_min = IPSET_TYPE_REV_MIN,
405 .revision_max = REVISION_MAX, 341 .revision_max = IPSET_TYPE_REV_MAX,
406 .create = bitmap_ip_create, 342 .create = bitmap_ip_create,
407 .create_policy = { 343 .create_policy = {
408 [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 344 [IPSET_ATTR_IP] = { .type = NLA_NESTED },
@@ -420,6 +356,7 @@ static struct ip_set_type bitmap_ip_type __read_mostly = {
420 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 356 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
421 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 357 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
422 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 358 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
359 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
423 }, 360 },
424 .me = THIS_MODULE, 361 .me = THIS_MODULE,
425}; 362};
diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
index 3b30e0bef890..740eabededd9 100644
--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
@@ -25,12 +25,13 @@
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 27
28#define REVISION_MIN 0 28#define IPSET_TYPE_REV_MIN 0
29#define REVISION_MAX 1 /* Counter support added */ 29/* 1 Counter support added */
30#define IPSET_TYPE_REV_MAX 2 /* Comment support added */
30 31
31MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 33MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
33IP_SET_MODULE_DESC("bitmap:ip,mac", REVISION_MIN, REVISION_MAX); 34IP_SET_MODULE_DESC("bitmap:ip,mac", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
34MODULE_ALIAS("ip_set_bitmap:ip,mac"); 35MODULE_ALIAS("ip_set_bitmap:ip,mac");
35 36
36#define MTYPE bitmap_ipmac 37#define MTYPE bitmap_ipmac
@@ -48,11 +49,8 @@ struct bitmap_ipmac {
48 u32 first_ip; /* host byte order, included in range */ 49 u32 first_ip; /* host byte order, included in range */
49 u32 last_ip; /* host byte order, included in range */ 50 u32 last_ip; /* host byte order, included in range */
50 u32 elements; /* number of max elements in the set */ 51 u32 elements; /* number of max elements in the set */
51 u32 timeout; /* timeout value */
52 struct timer_list gc; /* garbage collector */
53 size_t memsize; /* members size */ 52 size_t memsize; /* members size */
54 size_t dsize; /* size of element */ 53 struct timer_list gc; /* garbage collector */
55 size_t offset[IPSET_OFFSET_MAX]; /* Offsets to extensions */
56}; 54};
57 55
58/* ADT structure for generic function args */ 56/* ADT structure for generic function args */
@@ -82,13 +80,13 @@ get_elem(void *extensions, u16 id, size_t dsize)
82 80
83static inline int 81static inline int
84bitmap_ipmac_do_test(const struct bitmap_ipmac_adt_elem *e, 82bitmap_ipmac_do_test(const struct bitmap_ipmac_adt_elem *e,
85 const struct bitmap_ipmac *map) 83 const struct bitmap_ipmac *map, size_t dsize)
86{ 84{
87 const struct bitmap_ipmac_elem *elem; 85 const struct bitmap_ipmac_elem *elem;
88 86
89 if (!test_bit(e->id, map->members)) 87 if (!test_bit(e->id, map->members))
90 return 0; 88 return 0;
91 elem = get_elem(map->extensions, e->id, map->dsize); 89 elem = get_elem(map->extensions, e->id, dsize);
92 if (elem->filled == MAC_FILLED) 90 if (elem->filled == MAC_FILLED)
93 return e->ether == NULL || 91 return e->ether == NULL ||
94 ether_addr_equal(e->ether, elem->ether); 92 ether_addr_equal(e->ether, elem->ether);
@@ -97,13 +95,13 @@ bitmap_ipmac_do_test(const struct bitmap_ipmac_adt_elem *e,
97} 95}
98 96
99static inline int 97static inline int
100bitmap_ipmac_gc_test(u16 id, const struct bitmap_ipmac *map) 98bitmap_ipmac_gc_test(u16 id, const struct bitmap_ipmac *map, size_t dsize)
101{ 99{
102 const struct bitmap_ipmac_elem *elem; 100 const struct bitmap_ipmac_elem *elem;
103 101
104 if (!test_bit(id, map->members)) 102 if (!test_bit(id, map->members))
105 return 0; 103 return 0;
106 elem = get_elem(map->extensions, id, map->dsize); 104 elem = get_elem(map->extensions, id, dsize);
107 /* Timer not started for the incomplete elements */ 105 /* Timer not started for the incomplete elements */
108 return elem->filled == MAC_FILLED; 106 return elem->filled == MAC_FILLED;
109} 107}
@@ -117,13 +115,13 @@ bitmap_ipmac_is_filled(const struct bitmap_ipmac_elem *elem)
117static inline int 115static inline int
118bitmap_ipmac_add_timeout(unsigned long *timeout, 116bitmap_ipmac_add_timeout(unsigned long *timeout,
119 const struct bitmap_ipmac_adt_elem *e, 117 const struct bitmap_ipmac_adt_elem *e,
120 const struct ip_set_ext *ext, 118 const struct ip_set_ext *ext, struct ip_set *set,
121 struct bitmap_ipmac *map, int mode) 119 struct bitmap_ipmac *map, int mode)
122{ 120{
123 u32 t = ext->timeout; 121 u32 t = ext->timeout;
124 122
125 if (mode == IPSET_ADD_START_STORED_TIMEOUT) { 123 if (mode == IPSET_ADD_START_STORED_TIMEOUT) {
126 if (t == map->timeout) 124 if (t == set->timeout)
127 /* Timeout was not specified, get stored one */ 125 /* Timeout was not specified, get stored one */
128 t = *timeout; 126 t = *timeout;
129 ip_set_timeout_set(timeout, t); 127 ip_set_timeout_set(timeout, t);
@@ -142,11 +140,11 @@ bitmap_ipmac_add_timeout(unsigned long *timeout,
142 140
143static inline int 141static inline int
144bitmap_ipmac_do_add(const struct bitmap_ipmac_adt_elem *e, 142bitmap_ipmac_do_add(const struct bitmap_ipmac_adt_elem *e,
145 struct bitmap_ipmac *map, u32 flags) 143 struct bitmap_ipmac *map, u32 flags, size_t dsize)
146{ 144{
147 struct bitmap_ipmac_elem *elem; 145 struct bitmap_ipmac_elem *elem;
148 146
149 elem = get_elem(map->extensions, e->id, map->dsize); 147 elem = get_elem(map->extensions, e->id, dsize);
150 if (test_and_set_bit(e->id, map->members)) { 148 if (test_and_set_bit(e->id, map->members)) {
151 if (elem->filled == MAC_FILLED) { 149 if (elem->filled == MAC_FILLED) {
152 if (e->ether && (flags & IPSET_FLAG_EXIST)) 150 if (e->ether && (flags & IPSET_FLAG_EXIST))
@@ -178,22 +176,12 @@ bitmap_ipmac_do_del(const struct bitmap_ipmac_adt_elem *e,
178 return !test_and_clear_bit(e->id, map->members); 176 return !test_and_clear_bit(e->id, map->members);
179} 177}
180 178
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);
186
187 return elem->filled == MAC_FILLED ? ip_set_timeout_get(timeout) :
188 *timeout;
189}
190
191static inline int 179static inline int
192bitmap_ipmac_do_list(struct sk_buff *skb, const struct bitmap_ipmac *map, 180bitmap_ipmac_do_list(struct sk_buff *skb, const struct bitmap_ipmac *map,
193 u32 id) 181 u32 id, size_t dsize)
194{ 182{
195 const struct bitmap_ipmac_elem *elem = 183 const struct bitmap_ipmac_elem *elem =
196 get_elem(map->extensions, id, map->dsize); 184 get_elem(map->extensions, id, dsize);
197 185
198 return nla_put_ipaddr4(skb, IPSET_ATTR_IP, 186 return nla_put_ipaddr4(skb, IPSET_ATTR_IP,
199 htonl(map->first_ip + id)) || 187 htonl(map->first_ip + id)) ||
@@ -216,7 +204,7 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
216 struct bitmap_ipmac *map = set->data; 204 struct bitmap_ipmac *map = set->data;
217 ipset_adtfn adtfn = set->variant->adt[adt]; 205 ipset_adtfn adtfn = set->variant->adt[adt];
218 struct bitmap_ipmac_adt_elem e = {}; 206 struct bitmap_ipmac_adt_elem e = {};
219 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map); 207 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
220 u32 ip; 208 u32 ip;
221 209
222 /* MAC can be src only */ 210 /* MAC can be src only */
@@ -245,8 +233,8 @@ bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[],
245 const struct bitmap_ipmac *map = set->data; 233 const struct bitmap_ipmac *map = set->data;
246 ipset_adtfn adtfn = set->variant->adt[adt]; 234 ipset_adtfn adtfn = set->variant->adt[adt];
247 struct bitmap_ipmac_adt_elem e = {}; 235 struct bitmap_ipmac_adt_elem e = {};
248 struct ip_set_ext ext = IP_SET_INIT_UEXT(map); 236 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
249 u32 ip; 237 u32 ip = 0;
250 int ret = 0; 238 int ret = 0;
251 239
252 if (unlikely(!tb[IPSET_ATTR_IP] || 240 if (unlikely(!tb[IPSET_ATTR_IP] ||
@@ -285,43 +273,12 @@ bitmap_ipmac_same_set(const struct ip_set *a, const struct ip_set *b)
285 273
286 return x->first_ip == y->first_ip && 274 return x->first_ip == y->first_ip &&
287 x->last_ip == y->last_ip && 275 x->last_ip == y->last_ip &&
288 x->timeout == y->timeout && 276 a->timeout == b->timeout &&
289 a->extensions == b->extensions; 277 a->extensions == b->extensions;
290} 278}
291 279
292/* Plain variant */ 280/* Plain variant */
293 281
294/* Timeout variant */
295
296struct bitmap_ipmact_elem {
297 struct {
298 unsigned char ether[ETH_ALEN];
299 unsigned char filled;
300 } __attribute__ ((aligned));
301 unsigned long timeout;
302};
303
304/* Plain variant with counter */
305
306struct bitmap_ipmacc_elem {
307 struct {
308 unsigned char ether[ETH_ALEN];
309 unsigned char filled;
310 } __attribute__ ((aligned));
311 struct ip_set_counter counter;
312};
313
314/* Timeout variant with counter */
315
316struct bitmap_ipmacct_elem {
317 struct {
318 unsigned char ether[ETH_ALEN];
319 unsigned char filled;
320 } __attribute__ ((aligned));
321 unsigned long timeout;
322 struct ip_set_counter counter;
323};
324
325#include "ip_set_bitmap_gen.h" 282#include "ip_set_bitmap_gen.h"
326 283
327/* Create bitmap:ip,mac type of sets */ 284/* Create bitmap:ip,mac type of sets */
@@ -330,11 +287,11 @@ static bool
330init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map, 287init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
331 u32 first_ip, u32 last_ip, u32 elements) 288 u32 first_ip, u32 last_ip, u32 elements)
332{ 289{
333 map->members = ip_set_alloc((last_ip - first_ip + 1) * map->dsize); 290 map->members = ip_set_alloc(map->memsize);
334 if (!map->members) 291 if (!map->members)
335 return false; 292 return false;
336 if (map->dsize) { 293 if (set->dsize) {
337 map->extensions = ip_set_alloc(map->dsize * elements); 294 map->extensions = ip_set_alloc(set->dsize * elements);
338 if (!map->extensions) { 295 if (!map->extensions) {
339 kfree(map->members); 296 kfree(map->members);
340 return false; 297 return false;
@@ -343,7 +300,7 @@ init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
343 map->first_ip = first_ip; 300 map->first_ip = first_ip;
344 map->last_ip = last_ip; 301 map->last_ip = last_ip;
345 map->elements = elements; 302 map->elements = elements;
346 map->timeout = IPSET_NO_TIMEOUT; 303 set->timeout = IPSET_NO_TIMEOUT;
347 304
348 set->data = map; 305 set->data = map;
349 set->family = NFPROTO_IPV4; 306 set->family = NFPROTO_IPV4;
@@ -352,10 +309,10 @@ init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
352} 309}
353 310
354static int 311static int
355bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[], 312bitmap_ipmac_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
356 u32 flags) 313 u32 flags)
357{ 314{
358 u32 first_ip, last_ip, cadt_flags = 0; 315 u32 first_ip = 0, last_ip = 0;
359 u64 elements; 316 u64 elements;
360 struct bitmap_ipmac *map; 317 struct bitmap_ipmac *map;
361 int ret; 318 int ret;
@@ -399,57 +356,15 @@ bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[],
399 356
400 map->memsize = bitmap_bytes(0, elements - 1); 357 map->memsize = bitmap_bytes(0, elements - 1);
401 set->variant = &bitmap_ipmac; 358 set->variant = &bitmap_ipmac;
402 if (tb[IPSET_ATTR_CADT_FLAGS]) 359 set->dsize = ip_set_elem_len(set, tb,
403 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 360 sizeof(struct bitmap_ipmac_elem));
404 if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) { 361 if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) {
405 set->extensions |= IPSET_EXT_COUNTER; 362 kfree(map);
406 if (tb[IPSET_ATTR_TIMEOUT]) { 363 return -ENOMEM;
407 map->dsize = sizeof(struct bitmap_ipmacct_elem); 364 }
408 map->offset[IPSET_OFFSET_TIMEOUT] = 365 if (tb[IPSET_ATTR_TIMEOUT]) {
409 offsetof(struct bitmap_ipmacct_elem, timeout); 366 set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_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);
437
438 if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) {
439 kfree(map);
440 return -ENOMEM;
441 }
442 map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
443 set->extensions |= IPSET_EXT_TIMEOUT;
444 bitmap_ipmac_gc_init(set, bitmap_ipmac_gc); 367 bitmap_ipmac_gc_init(set, bitmap_ipmac_gc);
445 } else {
446 map->dsize = sizeof(struct bitmap_ipmac_elem);
447
448 if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) {
449 kfree(map);
450 return -ENOMEM;
451 }
452 set->variant = &bitmap_ipmac;
453 } 368 }
454 return 0; 369 return 0;
455} 370}
@@ -460,8 +375,8 @@ static struct ip_set_type bitmap_ipmac_type = {
460 .features = IPSET_TYPE_IP | IPSET_TYPE_MAC, 375 .features = IPSET_TYPE_IP | IPSET_TYPE_MAC,
461 .dimension = IPSET_DIM_TWO, 376 .dimension = IPSET_DIM_TWO,
462 .family = NFPROTO_IPV4, 377 .family = NFPROTO_IPV4,
463 .revision_min = REVISION_MIN, 378 .revision_min = IPSET_TYPE_REV_MIN,
464 .revision_max = REVISION_MAX, 379 .revision_max = IPSET_TYPE_REV_MAX,
465 .create = bitmap_ipmac_create, 380 .create = bitmap_ipmac_create,
466 .create_policy = { 381 .create_policy = {
467 [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 382 [IPSET_ATTR_IP] = { .type = NLA_NESTED },
@@ -478,6 +393,7 @@ static struct ip_set_type bitmap_ipmac_type = {
478 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 393 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
479 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 394 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
480 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 395 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
396 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
481 }, 397 },
482 .me = THIS_MODULE, 398 .me = THIS_MODULE,
483}; 399};
diff --git a/net/netfilter/ipset/ip_set_bitmap_port.c b/net/netfilter/ipset/ip_set_bitmap_port.c
index 8207d1fda528..e7603c5b53d7 100644
--- a/net/netfilter/ipset/ip_set_bitmap_port.c
+++ b/net/netfilter/ipset/ip_set_bitmap_port.c
@@ -20,12 +20,13 @@
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 22
23#define REVISION_MIN 0 23#define IPSET_TYPE_REV_MIN 0
24#define REVISION_MAX 1 /* Counter support added */ 24/* 1 Counter support added */
25#define IPSET_TYPE_REV_MAX 2 /* Comment support added */
25 26
26MODULE_LICENSE("GPL"); 27MODULE_LICENSE("GPL");
27MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 28MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
28IP_SET_MODULE_DESC("bitmap:port", REVISION_MIN, REVISION_MAX); 29IP_SET_MODULE_DESC("bitmap:port", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
29MODULE_ALIAS("ip_set_bitmap:port"); 30MODULE_ALIAS("ip_set_bitmap:port");
30 31
31#define MTYPE bitmap_port 32#define MTYPE bitmap_port
@@ -38,9 +39,6 @@ struct bitmap_port {
38 u16 last_port; /* host byte order, included in range */ 39 u16 last_port; /* host byte order, included in range */
39 u32 elements; /* number of max elements in the set */ 40 u32 elements; /* number of max elements in the set */
40 size_t memsize; /* members size */ 41 size_t memsize; /* members size */
41 size_t dsize; /* extensions struct size */
42 size_t offset[IPSET_OFFSET_MAX]; /* Offsets to extensions */
43 u32 timeout; /* timeout parameter */
44 struct timer_list gc; /* garbage collection */ 42 struct timer_list gc; /* garbage collection */
45}; 43};
46 44
@@ -59,20 +57,20 @@ port_to_id(const struct bitmap_port *m, u16 port)
59 57
60static inline int 58static inline int
61bitmap_port_do_test(const struct bitmap_port_adt_elem *e, 59bitmap_port_do_test(const struct bitmap_port_adt_elem *e,
62 const struct bitmap_port *map) 60 const struct bitmap_port *map, size_t dsize)
63{ 61{
64 return !!test_bit(e->id, map->members); 62 return !!test_bit(e->id, map->members);
65} 63}
66 64
67static inline int 65static inline int
68bitmap_port_gc_test(u16 id, const struct bitmap_port *map) 66bitmap_port_gc_test(u16 id, const struct bitmap_port *map, size_t dsize)
69{ 67{
70 return !!test_bit(id, map->members); 68 return !!test_bit(id, map->members);
71} 69}
72 70
73static inline int 71static inline int
74bitmap_port_do_add(const struct bitmap_port_adt_elem *e, 72bitmap_port_do_add(const struct bitmap_port_adt_elem *e,
75 struct bitmap_port *map, u32 flags) 73 struct bitmap_port *map, u32 flags, size_t dsize)
76{ 74{
77 return !!test_and_set_bit(e->id, map->members); 75 return !!test_and_set_bit(e->id, map->members);
78} 76}
@@ -85,7 +83,8 @@ bitmap_port_do_del(const struct bitmap_port_adt_elem *e,
85} 83}
86 84
87static inline int 85static inline int
88bitmap_port_do_list(struct sk_buff *skb, const struct bitmap_port *map, u32 id) 86bitmap_port_do_list(struct sk_buff *skb, const struct bitmap_port *map, u32 id,
87 size_t dsize)
89{ 88{
90 return nla_put_net16(skb, IPSET_ATTR_PORT, 89 return nla_put_net16(skb, IPSET_ATTR_PORT,
91 htons(map->first_port + id)); 90 htons(map->first_port + id));
@@ -106,7 +105,7 @@ bitmap_port_kadt(struct ip_set *set, const struct sk_buff *skb,
106 struct bitmap_port *map = set->data; 105 struct bitmap_port *map = set->data;
107 ipset_adtfn adtfn = set->variant->adt[adt]; 106 ipset_adtfn adtfn = set->variant->adt[adt];
108 struct bitmap_port_adt_elem e = {}; 107 struct bitmap_port_adt_elem e = {};
109 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map); 108 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
110 __be16 __port; 109 __be16 __port;
111 u16 port = 0; 110 u16 port = 0;
112 111
@@ -131,7 +130,7 @@ bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[],
131 struct bitmap_port *map = set->data; 130 struct bitmap_port *map = set->data;
132 ipset_adtfn adtfn = set->variant->adt[adt]; 131 ipset_adtfn adtfn = set->variant->adt[adt];
133 struct bitmap_port_adt_elem e = {}; 132 struct bitmap_port_adt_elem e = {};
134 struct ip_set_ext ext = IP_SET_INIT_UEXT(map); 133 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
135 u32 port; /* wraparound */ 134 u32 port; /* wraparound */
136 u16 port_to; 135 u16 port_to;
137 int ret = 0; 136 int ret = 0;
@@ -191,7 +190,7 @@ bitmap_port_same_set(const struct ip_set *a, const struct ip_set *b)
191 190
192 return x->first_port == y->first_port && 191 return x->first_port == y->first_port &&
193 x->last_port == y->last_port && 192 x->last_port == y->last_port &&
194 x->timeout == y->timeout && 193 a->timeout == b->timeout &&
195 a->extensions == b->extensions; 194 a->extensions == b->extensions;
196} 195}
197 196
@@ -200,25 +199,6 @@ bitmap_port_same_set(const struct ip_set *a, const struct ip_set *b)
200struct bitmap_port_elem { 199struct bitmap_port_elem {
201}; 200};
202 201
203/* Timeout variant */
204
205struct bitmap_portt_elem {
206 unsigned long timeout;
207};
208
209/* Plain variant with counter */
210
211struct bitmap_portc_elem {
212 struct ip_set_counter counter;
213};
214
215/* Timeout variant with counter */
216
217struct bitmap_portct_elem {
218 unsigned long timeout;
219 struct ip_set_counter counter;
220};
221
222#include "ip_set_bitmap_gen.h" 202#include "ip_set_bitmap_gen.h"
223 203
224/* Create bitmap:ip type of sets */ 204/* Create bitmap:ip type of sets */
@@ -230,8 +210,8 @@ init_map_port(struct ip_set *set, struct bitmap_port *map,
230 map->members = ip_set_alloc(map->memsize); 210 map->members = ip_set_alloc(map->memsize);
231 if (!map->members) 211 if (!map->members)
232 return false; 212 return false;
233 if (map->dsize) { 213 if (set->dsize) {
234 map->extensions = ip_set_alloc(map->dsize * map->elements); 214 map->extensions = ip_set_alloc(set->dsize * map->elements);
235 if (!map->extensions) { 215 if (!map->extensions) {
236 kfree(map->members); 216 kfree(map->members);
237 return false; 217 return false;
@@ -239,7 +219,7 @@ init_map_port(struct ip_set *set, struct bitmap_port *map,
239 } 219 }
240 map->first_port = first_port; 220 map->first_port = first_port;
241 map->last_port = last_port; 221 map->last_port = last_port;
242 map->timeout = IPSET_NO_TIMEOUT; 222 set->timeout = IPSET_NO_TIMEOUT;
243 223
244 set->data = map; 224 set->data = map;
245 set->family = NFPROTO_UNSPEC; 225 set->family = NFPROTO_UNSPEC;
@@ -248,11 +228,11 @@ init_map_port(struct ip_set *set, struct bitmap_port *map,
248} 228}
249 229
250static int 230static int
251bitmap_port_create(struct ip_set *set, struct nlattr *tb[], u32 flags) 231bitmap_port_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
232 u32 flags)
252{ 233{
253 struct bitmap_port *map; 234 struct bitmap_port *map;
254 u16 first_port, last_port; 235 u16 first_port, last_port;
255 u32 cadt_flags = 0;
256 236
257 if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || 237 if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
258 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) || 238 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) ||
@@ -276,53 +256,14 @@ bitmap_port_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
276 map->elements = last_port - first_port + 1; 256 map->elements = last_port - first_port + 1;
277 map->memsize = map->elements * sizeof(unsigned long); 257 map->memsize = map->elements * sizeof(unsigned long);
278 set->variant = &bitmap_port; 258 set->variant = &bitmap_port;
279 if (tb[IPSET_ATTR_CADT_FLAGS]) 259 set->dsize = ip_set_elem_len(set, tb, 0);
280 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 260 if (!init_map_port(set, map, first_port, last_port)) {
281 if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) { 261 kfree(map);
282 set->extensions |= IPSET_EXT_COUNTER; 262 return -ENOMEM;
283 if (tb[IPSET_ATTR_TIMEOUT]) { 263 }
284 map->dsize = sizeof(struct bitmap_portct_elem); 264 if (tb[IPSET_ATTR_TIMEOUT]) {
285 map->offset[IPSET_OFFSET_TIMEOUT] = 265 set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_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);
311 if (!init_map_port(set, map, first_port, last_port)) {
312 kfree(map);
313 return -ENOMEM;
314 }
315
316 map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
317 set->extensions |= IPSET_EXT_TIMEOUT;
318 bitmap_port_gc_init(set, bitmap_port_gc); 266 bitmap_port_gc_init(set, bitmap_port_gc);
319 } else {
320 map->dsize = 0;
321 if (!init_map_port(set, map, first_port, last_port)) {
322 kfree(map);
323 return -ENOMEM;
324 }
325
326 } 267 }
327 return 0; 268 return 0;
328} 269}
@@ -333,8 +274,8 @@ static struct ip_set_type bitmap_port_type = {
333 .features = IPSET_TYPE_PORT, 274 .features = IPSET_TYPE_PORT,
334 .dimension = IPSET_DIM_ONE, 275 .dimension = IPSET_DIM_ONE,
335 .family = NFPROTO_UNSPEC, 276 .family = NFPROTO_UNSPEC,
336 .revision_min = REVISION_MIN, 277 .revision_min = IPSET_TYPE_REV_MIN,
337 .revision_max = REVISION_MAX, 278 .revision_max = IPSET_TYPE_REV_MAX,
338 .create = bitmap_port_create, 279 .create = bitmap_port_create,
339 .create_policy = { 280 .create_policy = {
340 [IPSET_ATTR_PORT] = { .type = NLA_U16 }, 281 [IPSET_ATTR_PORT] = { .type = NLA_U16 },
@@ -349,6 +290,7 @@ static struct ip_set_type bitmap_port_type = {
349 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 290 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
350 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 291 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
351 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 292 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
293 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
352 }, 294 },
353 .me = THIS_MODULE, 295 .me = THIS_MODULE,
354}; 296};
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index f2e30fb31e78..dc9284bdd2dd 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -17,6 +17,8 @@
17#include <linux/spinlock.h> 17#include <linux/spinlock.h>
18#include <linux/rculist.h> 18#include <linux/rculist.h>
19#include <net/netlink.h> 19#include <net/netlink.h>
20#include <net/net_namespace.h>
21#include <net/netns/generic.h>
20 22
21#include <linux/netfilter.h> 23#include <linux/netfilter.h>
22#include <linux/netfilter/x_tables.h> 24#include <linux/netfilter/x_tables.h>
@@ -27,8 +29,17 @@ static LIST_HEAD(ip_set_type_list); /* all registered set types */
27static DEFINE_MUTEX(ip_set_type_mutex); /* protects ip_set_type_list */ 29static DEFINE_MUTEX(ip_set_type_mutex); /* protects ip_set_type_list */
28static DEFINE_RWLOCK(ip_set_ref_lock); /* protects the set refs */ 30static DEFINE_RWLOCK(ip_set_ref_lock); /* protects the set refs */
29 31
30static struct ip_set * __rcu *ip_set_list; /* all individual sets */ 32struct ip_set_net {
31static ip_set_id_t ip_set_max = CONFIG_IP_SET_MAX; /* max number of sets */ 33 struct ip_set * __rcu *ip_set_list; /* all individual sets */
34 ip_set_id_t ip_set_max; /* max number of sets */
35 int is_deleted; /* deleted by ip_set_net_exit */
36};
37static int ip_set_net_id __read_mostly;
38
39static inline struct ip_set_net *ip_set_pernet(struct net *net)
40{
41 return net_generic(net, ip_set_net_id);
42}
32 43
33#define IP_SET_INC 64 44#define IP_SET_INC 64
34#define STREQ(a, b) (strncmp(a, b, IPSET_MAXNAMELEN) == 0) 45#define STREQ(a, b) (strncmp(a, b, IPSET_MAXNAMELEN) == 0)
@@ -45,8 +56,8 @@ MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET);
45/* When the nfnl mutex is held: */ 56/* When the nfnl mutex is held: */
46#define nfnl_dereference(p) \ 57#define nfnl_dereference(p) \
47 rcu_dereference_protected(p, 1) 58 rcu_dereference_protected(p, 1)
48#define nfnl_set(id) \ 59#define nfnl_set(inst, id) \
49 nfnl_dereference(ip_set_list)[id] 60 nfnl_dereference((inst)->ip_set_list)[id]
50 61
51/* 62/*
52 * The set types are implemented in modules and registered set types 63 * The set types are implemented in modules and registered set types
@@ -315,6 +326,60 @@ ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr)
315} 326}
316EXPORT_SYMBOL_GPL(ip_set_get_ipaddr6); 327EXPORT_SYMBOL_GPL(ip_set_get_ipaddr6);
317 328
329typedef void (*destroyer)(void *);
330/* ipset data extension types, in size order */
331
332const struct ip_set_ext_type ip_set_extensions[] = {
333 [IPSET_EXT_ID_COUNTER] = {
334 .type = IPSET_EXT_COUNTER,
335 .flag = IPSET_FLAG_WITH_COUNTERS,
336 .len = sizeof(struct ip_set_counter),
337 .align = __alignof__(struct ip_set_counter),
338 },
339 [IPSET_EXT_ID_TIMEOUT] = {
340 .type = IPSET_EXT_TIMEOUT,
341 .len = sizeof(unsigned long),
342 .align = __alignof__(unsigned long),
343 },
344 [IPSET_EXT_ID_COMMENT] = {
345 .type = IPSET_EXT_COMMENT | IPSET_EXT_DESTROY,
346 .flag = IPSET_FLAG_WITH_COMMENT,
347 .len = sizeof(struct ip_set_comment),
348 .align = __alignof__(struct ip_set_comment),
349 .destroy = (destroyer) ip_set_comment_free,
350 },
351};
352EXPORT_SYMBOL_GPL(ip_set_extensions);
353
354static inline bool
355add_extension(enum ip_set_ext_id id, u32 flags, struct nlattr *tb[])
356{
357 return ip_set_extensions[id].flag ?
358 (flags & ip_set_extensions[id].flag) :
359 !!tb[IPSET_ATTR_TIMEOUT];
360}
361
362size_t
363ip_set_elem_len(struct ip_set *set, struct nlattr *tb[], size_t len)
364{
365 enum ip_set_ext_id id;
366 size_t offset = 0;
367 u32 cadt_flags = 0;
368
369 if (tb[IPSET_ATTR_CADT_FLAGS])
370 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
371 for (id = 0; id < IPSET_EXT_ID_MAX; id++) {
372 if (!add_extension(id, cadt_flags, tb))
373 continue;
374 offset += ALIGN(len + offset, ip_set_extensions[id].align);
375 set->offset[id] = offset;
376 set->extensions |= ip_set_extensions[id].type;
377 offset += ip_set_extensions[id].len;
378 }
379 return len + offset;
380}
381EXPORT_SYMBOL_GPL(ip_set_elem_len);
382
318int 383int
319ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[], 384ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
320 struct ip_set_ext *ext) 385 struct ip_set_ext *ext)
@@ -334,6 +399,12 @@ ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
334 ext->packets = be64_to_cpu(nla_get_be64( 399 ext->packets = be64_to_cpu(nla_get_be64(
335 tb[IPSET_ATTR_PACKETS])); 400 tb[IPSET_ATTR_PACKETS]));
336 } 401 }
402 if (tb[IPSET_ATTR_COMMENT]) {
403 if (!(set->extensions & IPSET_EXT_COMMENT))
404 return -IPSET_ERR_COMMENT;
405 ext->comment = ip_set_comment_uget(tb[IPSET_ATTR_COMMENT]);
406 }
407
337 return 0; 408 return 0;
338} 409}
339EXPORT_SYMBOL_GPL(ip_set_get_extensions); 410EXPORT_SYMBOL_GPL(ip_set_get_extensions);
@@ -374,13 +445,14 @@ __ip_set_put(struct ip_set *set)
374 */ 445 */
375 446
376static inline struct ip_set * 447static inline struct ip_set *
377ip_set_rcu_get(ip_set_id_t index) 448ip_set_rcu_get(struct net *net, ip_set_id_t index)
378{ 449{
379 struct ip_set *set; 450 struct ip_set *set;
451 struct ip_set_net *inst = ip_set_pernet(net);
380 452
381 rcu_read_lock(); 453 rcu_read_lock();
382 /* ip_set_list itself needs to be protected */ 454 /* ip_set_list itself needs to be protected */
383 set = rcu_dereference(ip_set_list)[index]; 455 set = rcu_dereference(inst->ip_set_list)[index];
384 rcu_read_unlock(); 456 rcu_read_unlock();
385 457
386 return set; 458 return set;
@@ -390,7 +462,8 @@ int
390ip_set_test(ip_set_id_t index, const struct sk_buff *skb, 462ip_set_test(ip_set_id_t index, const struct sk_buff *skb,
391 const struct xt_action_param *par, struct ip_set_adt_opt *opt) 463 const struct xt_action_param *par, struct ip_set_adt_opt *opt)
392{ 464{
393 struct ip_set *set = ip_set_rcu_get(index); 465 struct ip_set *set = ip_set_rcu_get(
466 dev_net(par->in ? par->in : par->out), index);
394 int ret = 0; 467 int ret = 0;
395 468
396 BUG_ON(set == NULL); 469 BUG_ON(set == NULL);
@@ -428,7 +501,8 @@ int
428ip_set_add(ip_set_id_t index, const struct sk_buff *skb, 501ip_set_add(ip_set_id_t index, const struct sk_buff *skb,
429 const struct xt_action_param *par, struct ip_set_adt_opt *opt) 502 const struct xt_action_param *par, struct ip_set_adt_opt *opt)
430{ 503{
431 struct ip_set *set = ip_set_rcu_get(index); 504 struct ip_set *set = ip_set_rcu_get(
505 dev_net(par->in ? par->in : par->out), index);
432 int ret; 506 int ret;
433 507
434 BUG_ON(set == NULL); 508 BUG_ON(set == NULL);
@@ -450,7 +524,8 @@ int
450ip_set_del(ip_set_id_t index, const struct sk_buff *skb, 524ip_set_del(ip_set_id_t index, const struct sk_buff *skb,
451 const struct xt_action_param *par, struct ip_set_adt_opt *opt) 525 const struct xt_action_param *par, struct ip_set_adt_opt *opt)
452{ 526{
453 struct ip_set *set = ip_set_rcu_get(index); 527 struct ip_set *set = ip_set_rcu_get(
528 dev_net(par->in ? par->in : par->out), index);
454 int ret = 0; 529 int ret = 0;
455 530
456 BUG_ON(set == NULL); 531 BUG_ON(set == NULL);
@@ -474,14 +549,15 @@ EXPORT_SYMBOL_GPL(ip_set_del);
474 * 549 *
475 */ 550 */
476ip_set_id_t 551ip_set_id_t
477ip_set_get_byname(const char *name, struct ip_set **set) 552ip_set_get_byname(struct net *net, const char *name, struct ip_set **set)
478{ 553{
479 ip_set_id_t i, index = IPSET_INVALID_ID; 554 ip_set_id_t i, index = IPSET_INVALID_ID;
480 struct ip_set *s; 555 struct ip_set *s;
556 struct ip_set_net *inst = ip_set_pernet(net);
481 557
482 rcu_read_lock(); 558 rcu_read_lock();
483 for (i = 0; i < ip_set_max; i++) { 559 for (i = 0; i < inst->ip_set_max; i++) {
484 s = rcu_dereference(ip_set_list)[i]; 560 s = rcu_dereference(inst->ip_set_list)[i];
485 if (s != NULL && STREQ(s->name, name)) { 561 if (s != NULL && STREQ(s->name, name)) {
486 __ip_set_get(s); 562 __ip_set_get(s);
487 index = i; 563 index = i;
@@ -501,17 +577,26 @@ EXPORT_SYMBOL_GPL(ip_set_get_byname);
501 * to be valid, after calling this function. 577 * to be valid, after calling this function.
502 * 578 *
503 */ 579 */
504void 580
505ip_set_put_byindex(ip_set_id_t index) 581static inline void
582__ip_set_put_byindex(struct ip_set_net *inst, ip_set_id_t index)
506{ 583{
507 struct ip_set *set; 584 struct ip_set *set;
508 585
509 rcu_read_lock(); 586 rcu_read_lock();
510 set = rcu_dereference(ip_set_list)[index]; 587 set = rcu_dereference(inst->ip_set_list)[index];
511 if (set != NULL) 588 if (set != NULL)
512 __ip_set_put(set); 589 __ip_set_put(set);
513 rcu_read_unlock(); 590 rcu_read_unlock();
514} 591}
592
593void
594ip_set_put_byindex(struct net *net, ip_set_id_t index)
595{
596 struct ip_set_net *inst = ip_set_pernet(net);
597
598 __ip_set_put_byindex(inst, index);
599}
515EXPORT_SYMBOL_GPL(ip_set_put_byindex); 600EXPORT_SYMBOL_GPL(ip_set_put_byindex);
516 601
517/* 602/*
@@ -522,9 +607,9 @@ EXPORT_SYMBOL_GPL(ip_set_put_byindex);
522 * 607 *
523 */ 608 */
524const char * 609const char *
525ip_set_name_byindex(ip_set_id_t index) 610ip_set_name_byindex(struct net *net, ip_set_id_t index)
526{ 611{
527 const struct ip_set *set = ip_set_rcu_get(index); 612 const struct ip_set *set = ip_set_rcu_get(net, index);
528 613
529 BUG_ON(set == NULL); 614 BUG_ON(set == NULL);
530 BUG_ON(set->ref == 0); 615 BUG_ON(set->ref == 0);
@@ -546,14 +631,15 @@ EXPORT_SYMBOL_GPL(ip_set_name_byindex);
546 * The nfnl mutex is used in the function. 631 * The nfnl mutex is used in the function.
547 */ 632 */
548ip_set_id_t 633ip_set_id_t
549ip_set_nfnl_get(const char *name) 634ip_set_nfnl_get(struct net *net, const char *name)
550{ 635{
551 ip_set_id_t i, index = IPSET_INVALID_ID; 636 ip_set_id_t i, index = IPSET_INVALID_ID;
552 struct ip_set *s; 637 struct ip_set *s;
638 struct ip_set_net *inst = ip_set_pernet(net);
553 639
554 nfnl_lock(NFNL_SUBSYS_IPSET); 640 nfnl_lock(NFNL_SUBSYS_IPSET);
555 for (i = 0; i < ip_set_max; i++) { 641 for (i = 0; i < inst->ip_set_max; i++) {
556 s = nfnl_set(i); 642 s = nfnl_set(inst, i);
557 if (s != NULL && STREQ(s->name, name)) { 643 if (s != NULL && STREQ(s->name, name)) {
558 __ip_set_get(s); 644 __ip_set_get(s);
559 index = i; 645 index = i;
@@ -573,15 +659,16 @@ EXPORT_SYMBOL_GPL(ip_set_nfnl_get);
573 * The nfnl mutex is used in the function. 659 * The nfnl mutex is used in the function.
574 */ 660 */
575ip_set_id_t 661ip_set_id_t
576ip_set_nfnl_get_byindex(ip_set_id_t index) 662ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index)
577{ 663{
578 struct ip_set *set; 664 struct ip_set *set;
665 struct ip_set_net *inst = ip_set_pernet(net);
579 666
580 if (index > ip_set_max) 667 if (index > inst->ip_set_max)
581 return IPSET_INVALID_ID; 668 return IPSET_INVALID_ID;
582 669
583 nfnl_lock(NFNL_SUBSYS_IPSET); 670 nfnl_lock(NFNL_SUBSYS_IPSET);
584 set = nfnl_set(index); 671 set = nfnl_set(inst, index);
585 if (set) 672 if (set)
586 __ip_set_get(set); 673 __ip_set_get(set);
587 else 674 else
@@ -600,13 +687,17 @@ EXPORT_SYMBOL_GPL(ip_set_nfnl_get_byindex);
600 * The nfnl mutex is used in the function. 687 * The nfnl mutex is used in the function.
601 */ 688 */
602void 689void
603ip_set_nfnl_put(ip_set_id_t index) 690ip_set_nfnl_put(struct net *net, ip_set_id_t index)
604{ 691{
605 struct ip_set *set; 692 struct ip_set *set;
693 struct ip_set_net *inst = ip_set_pernet(net);
694
606 nfnl_lock(NFNL_SUBSYS_IPSET); 695 nfnl_lock(NFNL_SUBSYS_IPSET);
607 set = nfnl_set(index); 696 if (!inst->is_deleted) { /* already deleted from ip_set_net_exit() */
608 if (set != NULL) 697 set = nfnl_set(inst, index);
609 __ip_set_put(set); 698 if (set != NULL)
699 __ip_set_put(set);
700 }
610 nfnl_unlock(NFNL_SUBSYS_IPSET); 701 nfnl_unlock(NFNL_SUBSYS_IPSET);
611} 702}
612EXPORT_SYMBOL_GPL(ip_set_nfnl_put); 703EXPORT_SYMBOL_GPL(ip_set_nfnl_put);
@@ -664,14 +755,14 @@ static const struct nla_policy ip_set_create_policy[IPSET_ATTR_CMD_MAX + 1] = {
664}; 755};
665 756
666static struct ip_set * 757static struct ip_set *
667find_set_and_id(const char *name, ip_set_id_t *id) 758find_set_and_id(struct ip_set_net *inst, const char *name, ip_set_id_t *id)
668{ 759{
669 struct ip_set *set = NULL; 760 struct ip_set *set = NULL;
670 ip_set_id_t i; 761 ip_set_id_t i;
671 762
672 *id = IPSET_INVALID_ID; 763 *id = IPSET_INVALID_ID;
673 for (i = 0; i < ip_set_max; i++) { 764 for (i = 0; i < inst->ip_set_max; i++) {
674 set = nfnl_set(i); 765 set = nfnl_set(inst, i);
675 if (set != NULL && STREQ(set->name, name)) { 766 if (set != NULL && STREQ(set->name, name)) {
676 *id = i; 767 *id = i;
677 break; 768 break;
@@ -681,22 +772,23 @@ find_set_and_id(const char *name, ip_set_id_t *id)
681} 772}
682 773
683static inline struct ip_set * 774static inline struct ip_set *
684find_set(const char *name) 775find_set(struct ip_set_net *inst, const char *name)
685{ 776{
686 ip_set_id_t id; 777 ip_set_id_t id;
687 778
688 return find_set_and_id(name, &id); 779 return find_set_and_id(inst, name, &id);
689} 780}
690 781
691static int 782static int
692find_free_id(const char *name, ip_set_id_t *index, struct ip_set **set) 783find_free_id(struct ip_set_net *inst, const char *name, ip_set_id_t *index,
784 struct ip_set **set)
693{ 785{
694 struct ip_set *s; 786 struct ip_set *s;
695 ip_set_id_t i; 787 ip_set_id_t i;
696 788
697 *index = IPSET_INVALID_ID; 789 *index = IPSET_INVALID_ID;
698 for (i = 0; i < ip_set_max; i++) { 790 for (i = 0; i < inst->ip_set_max; i++) {
699 s = nfnl_set(i); 791 s = nfnl_set(inst, i);
700 if (s == NULL) { 792 if (s == NULL) {
701 if (*index == IPSET_INVALID_ID) 793 if (*index == IPSET_INVALID_ID)
702 *index = i; 794 *index = i;
@@ -725,6 +817,8 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb,
725 const struct nlmsghdr *nlh, 817 const struct nlmsghdr *nlh,
726 const struct nlattr * const attr[]) 818 const struct nlattr * const attr[])
727{ 819{
820 struct net *net = sock_net(ctnl);
821 struct ip_set_net *inst = ip_set_pernet(net);
728 struct ip_set *set, *clash = NULL; 822 struct ip_set *set, *clash = NULL;
729 ip_set_id_t index = IPSET_INVALID_ID; 823 ip_set_id_t index = IPSET_INVALID_ID;
730 struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1] = {}; 824 struct nlattr *tb[IPSET_ATTR_CREATE_MAX+1] = {};
@@ -783,7 +877,7 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb,
783 goto put_out; 877 goto put_out;
784 } 878 }
785 879
786 ret = set->type->create(set, tb, flags); 880 ret = set->type->create(net, set, tb, flags);
787 if (ret != 0) 881 if (ret != 0)
788 goto put_out; 882 goto put_out;
789 883
@@ -794,7 +888,7 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb,
794 * by the nfnl mutex. Find the first free index in ip_set_list 888 * by the nfnl mutex. Find the first free index in ip_set_list
795 * and check clashing. 889 * and check clashing.
796 */ 890 */
797 ret = find_free_id(set->name, &index, &clash); 891 ret = find_free_id(inst, set->name, &index, &clash);
798 if (ret == -EEXIST) { 892 if (ret == -EEXIST) {
799 /* If this is the same set and requested, ignore error */ 893 /* If this is the same set and requested, ignore error */
800 if ((flags & IPSET_FLAG_EXIST) && 894 if ((flags & IPSET_FLAG_EXIST) &&
@@ -807,9 +901,9 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb,
807 goto cleanup; 901 goto cleanup;
808 } else if (ret == -IPSET_ERR_MAX_SETS) { 902 } else if (ret == -IPSET_ERR_MAX_SETS) {
809 struct ip_set **list, **tmp; 903 struct ip_set **list, **tmp;
810 ip_set_id_t i = ip_set_max + IP_SET_INC; 904 ip_set_id_t i = inst->ip_set_max + IP_SET_INC;
811 905
812 if (i < ip_set_max || i == IPSET_INVALID_ID) 906 if (i < inst->ip_set_max || i == IPSET_INVALID_ID)
813 /* Wraparound */ 907 /* Wraparound */
814 goto cleanup; 908 goto cleanup;
815 909
@@ -817,14 +911,14 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb,
817 if (!list) 911 if (!list)
818 goto cleanup; 912 goto cleanup;
819 /* nfnl mutex is held, both lists are valid */ 913 /* nfnl mutex is held, both lists are valid */
820 tmp = nfnl_dereference(ip_set_list); 914 tmp = nfnl_dereference(inst->ip_set_list);
821 memcpy(list, tmp, sizeof(struct ip_set *) * ip_set_max); 915 memcpy(list, tmp, sizeof(struct ip_set *) * inst->ip_set_max);
822 rcu_assign_pointer(ip_set_list, list); 916 rcu_assign_pointer(inst->ip_set_list, list);
823 /* Make sure all current packets have passed through */ 917 /* Make sure all current packets have passed through */
824 synchronize_net(); 918 synchronize_net();
825 /* Use new list */ 919 /* Use new list */
826 index = ip_set_max; 920 index = inst->ip_set_max;
827 ip_set_max = i; 921 inst->ip_set_max = i;
828 kfree(tmp); 922 kfree(tmp);
829 ret = 0; 923 ret = 0;
830 } else if (ret) 924 } else if (ret)
@@ -834,7 +928,7 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb,
834 * Finally! Add our shiny new set to the list, and be done. 928 * Finally! Add our shiny new set to the list, and be done.
835 */ 929 */
836 pr_debug("create: '%s' created with index %u!\n", set->name, index); 930 pr_debug("create: '%s' created with index %u!\n", set->name, index);
837 nfnl_set(index) = set; 931 nfnl_set(inst, index) = set;
838 932
839 return ret; 933 return ret;
840 934
@@ -857,12 +951,12 @@ ip_set_setname_policy[IPSET_ATTR_CMD_MAX + 1] = {
857}; 951};
858 952
859static void 953static void
860ip_set_destroy_set(ip_set_id_t index) 954ip_set_destroy_set(struct ip_set_net *inst, ip_set_id_t index)
861{ 955{
862 struct ip_set *set = nfnl_set(index); 956 struct ip_set *set = nfnl_set(inst, index);
863 957
864 pr_debug("set: %s\n", set->name); 958 pr_debug("set: %s\n", set->name);
865 nfnl_set(index) = NULL; 959 nfnl_set(inst, index) = NULL;
866 960
867 /* Must call it without holding any lock */ 961 /* Must call it without holding any lock */
868 set->variant->destroy(set); 962 set->variant->destroy(set);
@@ -875,6 +969,7 @@ ip_set_destroy(struct sock *ctnl, struct sk_buff *skb,
875 const struct nlmsghdr *nlh, 969 const struct nlmsghdr *nlh,
876 const struct nlattr * const attr[]) 970 const struct nlattr * const attr[])
877{ 971{
972 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl));
878 struct ip_set *s; 973 struct ip_set *s;
879 ip_set_id_t i; 974 ip_set_id_t i;
880 int ret = 0; 975 int ret = 0;
@@ -894,21 +989,22 @@ ip_set_destroy(struct sock *ctnl, struct sk_buff *skb,
894 */ 989 */
895 read_lock_bh(&ip_set_ref_lock); 990 read_lock_bh(&ip_set_ref_lock);
896 if (!attr[IPSET_ATTR_SETNAME]) { 991 if (!attr[IPSET_ATTR_SETNAME]) {
897 for (i = 0; i < ip_set_max; i++) { 992 for (i = 0; i < inst->ip_set_max; i++) {
898 s = nfnl_set(i); 993 s = nfnl_set(inst, i);
899 if (s != NULL && s->ref) { 994 if (s != NULL && s->ref) {
900 ret = -IPSET_ERR_BUSY; 995 ret = -IPSET_ERR_BUSY;
901 goto out; 996 goto out;
902 } 997 }
903 } 998 }
904 read_unlock_bh(&ip_set_ref_lock); 999 read_unlock_bh(&ip_set_ref_lock);
905 for (i = 0; i < ip_set_max; i++) { 1000 for (i = 0; i < inst->ip_set_max; i++) {
906 s = nfnl_set(i); 1001 s = nfnl_set(inst, i);
907 if (s != NULL) 1002 if (s != NULL)
908 ip_set_destroy_set(i); 1003 ip_set_destroy_set(inst, i);
909 } 1004 }
910 } else { 1005 } else {
911 s = find_set_and_id(nla_data(attr[IPSET_ATTR_SETNAME]), &i); 1006 s = find_set_and_id(inst, nla_data(attr[IPSET_ATTR_SETNAME]),
1007 &i);
912 if (s == NULL) { 1008 if (s == NULL) {
913 ret = -ENOENT; 1009 ret = -ENOENT;
914 goto out; 1010 goto out;
@@ -918,7 +1014,7 @@ ip_set_destroy(struct sock *ctnl, struct sk_buff *skb,
918 } 1014 }
919 read_unlock_bh(&ip_set_ref_lock); 1015 read_unlock_bh(&ip_set_ref_lock);
920 1016
921 ip_set_destroy_set(i); 1017 ip_set_destroy_set(inst, i);
922 } 1018 }
923 return 0; 1019 return 0;
924out: 1020out:
@@ -943,6 +1039,7 @@ ip_set_flush(struct sock *ctnl, struct sk_buff *skb,
943 const struct nlmsghdr *nlh, 1039 const struct nlmsghdr *nlh,
944 const struct nlattr * const attr[]) 1040 const struct nlattr * const attr[])
945{ 1041{
1042 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl));
946 struct ip_set *s; 1043 struct ip_set *s;
947 ip_set_id_t i; 1044 ip_set_id_t i;
948 1045
@@ -950,13 +1047,13 @@ ip_set_flush(struct sock *ctnl, struct sk_buff *skb,
950 return -IPSET_ERR_PROTOCOL; 1047 return -IPSET_ERR_PROTOCOL;
951 1048
952 if (!attr[IPSET_ATTR_SETNAME]) { 1049 if (!attr[IPSET_ATTR_SETNAME]) {
953 for (i = 0; i < ip_set_max; i++) { 1050 for (i = 0; i < inst->ip_set_max; i++) {
954 s = nfnl_set(i); 1051 s = nfnl_set(inst, i);
955 if (s != NULL) 1052 if (s != NULL)
956 ip_set_flush_set(s); 1053 ip_set_flush_set(s);
957 } 1054 }
958 } else { 1055 } else {
959 s = find_set(nla_data(attr[IPSET_ATTR_SETNAME])); 1056 s = find_set(inst, nla_data(attr[IPSET_ATTR_SETNAME]));
960 if (s == NULL) 1057 if (s == NULL)
961 return -ENOENT; 1058 return -ENOENT;
962 1059
@@ -982,6 +1079,7 @@ ip_set_rename(struct sock *ctnl, struct sk_buff *skb,
982 const struct nlmsghdr *nlh, 1079 const struct nlmsghdr *nlh,
983 const struct nlattr * const attr[]) 1080 const struct nlattr * const attr[])
984{ 1081{
1082 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl));
985 struct ip_set *set, *s; 1083 struct ip_set *set, *s;
986 const char *name2; 1084 const char *name2;
987 ip_set_id_t i; 1085 ip_set_id_t i;
@@ -992,7 +1090,7 @@ ip_set_rename(struct sock *ctnl, struct sk_buff *skb,
992 attr[IPSET_ATTR_SETNAME2] == NULL)) 1090 attr[IPSET_ATTR_SETNAME2] == NULL))
993 return -IPSET_ERR_PROTOCOL; 1091 return -IPSET_ERR_PROTOCOL;
994 1092
995 set = find_set(nla_data(attr[IPSET_ATTR_SETNAME])); 1093 set = find_set(inst, nla_data(attr[IPSET_ATTR_SETNAME]));
996 if (set == NULL) 1094 if (set == NULL)
997 return -ENOENT; 1095 return -ENOENT;
998 1096
@@ -1003,8 +1101,8 @@ ip_set_rename(struct sock *ctnl, struct sk_buff *skb,
1003 } 1101 }
1004 1102
1005 name2 = nla_data(attr[IPSET_ATTR_SETNAME2]); 1103 name2 = nla_data(attr[IPSET_ATTR_SETNAME2]);
1006 for (i = 0; i < ip_set_max; i++) { 1104 for (i = 0; i < inst->ip_set_max; i++) {
1007 s = nfnl_set(i); 1105 s = nfnl_set(inst, i);
1008 if (s != NULL && STREQ(s->name, name2)) { 1106 if (s != NULL && STREQ(s->name, name2)) {
1009 ret = -IPSET_ERR_EXIST_SETNAME2; 1107 ret = -IPSET_ERR_EXIST_SETNAME2;
1010 goto out; 1108 goto out;
@@ -1031,6 +1129,7 @@ ip_set_swap(struct sock *ctnl, struct sk_buff *skb,
1031 const struct nlmsghdr *nlh, 1129 const struct nlmsghdr *nlh,
1032 const struct nlattr * const attr[]) 1130 const struct nlattr * const attr[])
1033{ 1131{
1132 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl));
1034 struct ip_set *from, *to; 1133 struct ip_set *from, *to;
1035 ip_set_id_t from_id, to_id; 1134 ip_set_id_t from_id, to_id;
1036 char from_name[IPSET_MAXNAMELEN]; 1135 char from_name[IPSET_MAXNAMELEN];
@@ -1040,11 +1139,13 @@ ip_set_swap(struct sock *ctnl, struct sk_buff *skb,
1040 attr[IPSET_ATTR_SETNAME2] == NULL)) 1139 attr[IPSET_ATTR_SETNAME2] == NULL))
1041 return -IPSET_ERR_PROTOCOL; 1140 return -IPSET_ERR_PROTOCOL;
1042 1141
1043 from = find_set_and_id(nla_data(attr[IPSET_ATTR_SETNAME]), &from_id); 1142 from = find_set_and_id(inst, nla_data(attr[IPSET_ATTR_SETNAME]),
1143 &from_id);
1044 if (from == NULL) 1144 if (from == NULL)
1045 return -ENOENT; 1145 return -ENOENT;
1046 1146
1047 to = find_set_and_id(nla_data(attr[IPSET_ATTR_SETNAME2]), &to_id); 1147 to = find_set_and_id(inst, nla_data(attr[IPSET_ATTR_SETNAME2]),
1148 &to_id);
1048 if (to == NULL) 1149 if (to == NULL)
1049 return -IPSET_ERR_EXIST_SETNAME2; 1150 return -IPSET_ERR_EXIST_SETNAME2;
1050 1151
@@ -1061,8 +1162,8 @@ ip_set_swap(struct sock *ctnl, struct sk_buff *skb,
1061 1162
1062 write_lock_bh(&ip_set_ref_lock); 1163 write_lock_bh(&ip_set_ref_lock);
1063 swap(from->ref, to->ref); 1164 swap(from->ref, to->ref);
1064 nfnl_set(from_id) = to; 1165 nfnl_set(inst, from_id) = to;
1065 nfnl_set(to_id) = from; 1166 nfnl_set(inst, to_id) = from;
1066 write_unlock_bh(&ip_set_ref_lock); 1167 write_unlock_bh(&ip_set_ref_lock);
1067 1168
1068 return 0; 1169 return 0;
@@ -1081,9 +1182,10 @@ ip_set_swap(struct sock *ctnl, struct sk_buff *skb,
1081static int 1182static int
1082ip_set_dump_done(struct netlink_callback *cb) 1183ip_set_dump_done(struct netlink_callback *cb)
1083{ 1184{
1185 struct ip_set_net *inst = (struct ip_set_net *)cb->data;
1084 if (cb->args[2]) { 1186 if (cb->args[2]) {
1085 pr_debug("release set %s\n", nfnl_set(cb->args[1])->name); 1187 pr_debug("release set %s\n", nfnl_set(inst, cb->args[1])->name);
1086 ip_set_put_byindex((ip_set_id_t) cb->args[1]); 1188 __ip_set_put_byindex(inst, (ip_set_id_t) cb->args[1]);
1087 } 1189 }
1088 return 0; 1190 return 0;
1089} 1191}
@@ -1109,6 +1211,7 @@ dump_init(struct netlink_callback *cb)
1109 struct nlattr *attr = (void *)nlh + min_len; 1211 struct nlattr *attr = (void *)nlh + min_len;
1110 u32 dump_type; 1212 u32 dump_type;
1111 ip_set_id_t index; 1213 ip_set_id_t index;
1214 struct ip_set_net *inst = (struct ip_set_net *)cb->data;
1112 1215
1113 /* Second pass, so parser can't fail */ 1216 /* Second pass, so parser can't fail */
1114 nla_parse(cda, IPSET_ATTR_CMD_MAX, 1217 nla_parse(cda, IPSET_ATTR_CMD_MAX,
@@ -1122,7 +1225,7 @@ dump_init(struct netlink_callback *cb)
1122 if (cda[IPSET_ATTR_SETNAME]) { 1225 if (cda[IPSET_ATTR_SETNAME]) {
1123 struct ip_set *set; 1226 struct ip_set *set;
1124 1227
1125 set = find_set_and_id(nla_data(cda[IPSET_ATTR_SETNAME]), 1228 set = find_set_and_id(inst, nla_data(cda[IPSET_ATTR_SETNAME]),
1126 &index); 1229 &index);
1127 if (set == NULL) 1230 if (set == NULL)
1128 return -ENOENT; 1231 return -ENOENT;
@@ -1150,6 +1253,7 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
1150 unsigned int flags = NETLINK_CB(cb->skb).portid ? NLM_F_MULTI : 0; 1253 unsigned int flags = NETLINK_CB(cb->skb).portid ? NLM_F_MULTI : 0;
1151 u32 dump_type, dump_flags; 1254 u32 dump_type, dump_flags;
1152 int ret = 0; 1255 int ret = 0;
1256 struct ip_set_net *inst = (struct ip_set_net *)cb->data;
1153 1257
1154 if (!cb->args[0]) { 1258 if (!cb->args[0]) {
1155 ret = dump_init(cb); 1259 ret = dump_init(cb);
@@ -1163,18 +1267,18 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
1163 } 1267 }
1164 } 1268 }
1165 1269
1166 if (cb->args[1] >= ip_set_max) 1270 if (cb->args[1] >= inst->ip_set_max)
1167 goto out; 1271 goto out;
1168 1272
1169 dump_type = DUMP_TYPE(cb->args[0]); 1273 dump_type = DUMP_TYPE(cb->args[0]);
1170 dump_flags = DUMP_FLAGS(cb->args[0]); 1274 dump_flags = DUMP_FLAGS(cb->args[0]);
1171 max = dump_type == DUMP_ONE ? cb->args[1] + 1 : ip_set_max; 1275 max = dump_type == DUMP_ONE ? cb->args[1] + 1 : inst->ip_set_max;
1172dump_last: 1276dump_last:
1173 pr_debug("args[0]: %u %u args[1]: %ld\n", 1277 pr_debug("args[0]: %u %u args[1]: %ld\n",
1174 dump_type, dump_flags, cb->args[1]); 1278 dump_type, dump_flags, cb->args[1]);
1175 for (; cb->args[1] < max; cb->args[1]++) { 1279 for (; cb->args[1] < max; cb->args[1]++) {
1176 index = (ip_set_id_t) cb->args[1]; 1280 index = (ip_set_id_t) cb->args[1];
1177 set = nfnl_set(index); 1281 set = nfnl_set(inst, index);
1178 if (set == NULL) { 1282 if (set == NULL) {
1179 if (dump_type == DUMP_ONE) { 1283 if (dump_type == DUMP_ONE) {
1180 ret = -ENOENT; 1284 ret = -ENOENT;
@@ -1252,8 +1356,8 @@ next_set:
1252release_refcount: 1356release_refcount:
1253 /* If there was an error or set is done, release set */ 1357 /* If there was an error or set is done, release set */
1254 if (ret || !cb->args[2]) { 1358 if (ret || !cb->args[2]) {
1255 pr_debug("release set %s\n", nfnl_set(index)->name); 1359 pr_debug("release set %s\n", nfnl_set(inst, index)->name);
1256 ip_set_put_byindex(index); 1360 __ip_set_put_byindex(inst, index);
1257 cb->args[2] = 0; 1361 cb->args[2] = 0;
1258 } 1362 }
1259out: 1363out:
@@ -1271,6 +1375,8 @@ ip_set_dump(struct sock *ctnl, struct sk_buff *skb,
1271 const struct nlmsghdr *nlh, 1375 const struct nlmsghdr *nlh,
1272 const struct nlattr * const attr[]) 1376 const struct nlattr * const attr[])
1273{ 1377{
1378 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl));
1379
1274 if (unlikely(protocol_failed(attr))) 1380 if (unlikely(protocol_failed(attr)))
1275 return -IPSET_ERR_PROTOCOL; 1381 return -IPSET_ERR_PROTOCOL;
1276 1382
@@ -1278,6 +1384,7 @@ ip_set_dump(struct sock *ctnl, struct sk_buff *skb,
1278 struct netlink_dump_control c = { 1384 struct netlink_dump_control c = {
1279 .dump = ip_set_dump_start, 1385 .dump = ip_set_dump_start,
1280 .done = ip_set_dump_done, 1386 .done = ip_set_dump_done,
1387 .data = (void *)inst
1281 }; 1388 };
1282 return netlink_dump_start(ctnl, skb, nlh, &c); 1389 return netlink_dump_start(ctnl, skb, nlh, &c);
1283 } 1390 }
@@ -1356,6 +1463,7 @@ ip_set_uadd(struct sock *ctnl, struct sk_buff *skb,
1356 const struct nlmsghdr *nlh, 1463 const struct nlmsghdr *nlh,
1357 const struct nlattr * const attr[]) 1464 const struct nlattr * const attr[])
1358{ 1465{
1466 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl));
1359 struct ip_set *set; 1467 struct ip_set *set;
1360 struct nlattr *tb[IPSET_ATTR_ADT_MAX+1] = {}; 1468 struct nlattr *tb[IPSET_ATTR_ADT_MAX+1] = {};
1361 const struct nlattr *nla; 1469 const struct nlattr *nla;
@@ -1374,7 +1482,7 @@ ip_set_uadd(struct sock *ctnl, struct sk_buff *skb,
1374 attr[IPSET_ATTR_LINENO] == NULL)))) 1482 attr[IPSET_ATTR_LINENO] == NULL))))
1375 return -IPSET_ERR_PROTOCOL; 1483 return -IPSET_ERR_PROTOCOL;
1376 1484
1377 set = find_set(nla_data(attr[IPSET_ATTR_SETNAME])); 1485 set = find_set(inst, nla_data(attr[IPSET_ATTR_SETNAME]));
1378 if (set == NULL) 1486 if (set == NULL)
1379 return -ENOENT; 1487 return -ENOENT;
1380 1488
@@ -1410,6 +1518,7 @@ ip_set_udel(struct sock *ctnl, struct sk_buff *skb,
1410 const struct nlmsghdr *nlh, 1518 const struct nlmsghdr *nlh,
1411 const struct nlattr * const attr[]) 1519 const struct nlattr * const attr[])
1412{ 1520{
1521 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl));
1413 struct ip_set *set; 1522 struct ip_set *set;
1414 struct nlattr *tb[IPSET_ATTR_ADT_MAX+1] = {}; 1523 struct nlattr *tb[IPSET_ATTR_ADT_MAX+1] = {};
1415 const struct nlattr *nla; 1524 const struct nlattr *nla;
@@ -1428,7 +1537,7 @@ ip_set_udel(struct sock *ctnl, struct sk_buff *skb,
1428 attr[IPSET_ATTR_LINENO] == NULL)))) 1537 attr[IPSET_ATTR_LINENO] == NULL))))
1429 return -IPSET_ERR_PROTOCOL; 1538 return -IPSET_ERR_PROTOCOL;
1430 1539
1431 set = find_set(nla_data(attr[IPSET_ATTR_SETNAME])); 1540 set = find_set(inst, nla_data(attr[IPSET_ATTR_SETNAME]));
1432 if (set == NULL) 1541 if (set == NULL)
1433 return -ENOENT; 1542 return -ENOENT;
1434 1543
@@ -1464,6 +1573,7 @@ ip_set_utest(struct sock *ctnl, struct sk_buff *skb,
1464 const struct nlmsghdr *nlh, 1573 const struct nlmsghdr *nlh,
1465 const struct nlattr * const attr[]) 1574 const struct nlattr * const attr[])
1466{ 1575{
1576 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl));
1467 struct ip_set *set; 1577 struct ip_set *set;
1468 struct nlattr *tb[IPSET_ATTR_ADT_MAX+1] = {}; 1578 struct nlattr *tb[IPSET_ATTR_ADT_MAX+1] = {};
1469 int ret = 0; 1579 int ret = 0;
@@ -1474,7 +1584,7 @@ ip_set_utest(struct sock *ctnl, struct sk_buff *skb,
1474 !flag_nested(attr[IPSET_ATTR_DATA]))) 1584 !flag_nested(attr[IPSET_ATTR_DATA])))
1475 return -IPSET_ERR_PROTOCOL; 1585 return -IPSET_ERR_PROTOCOL;
1476 1586
1477 set = find_set(nla_data(attr[IPSET_ATTR_SETNAME])); 1587 set = find_set(inst, nla_data(attr[IPSET_ATTR_SETNAME]));
1478 if (set == NULL) 1588 if (set == NULL)
1479 return -ENOENT; 1589 return -ENOENT;
1480 1590
@@ -1499,6 +1609,7 @@ ip_set_header(struct sock *ctnl, struct sk_buff *skb,
1499 const struct nlmsghdr *nlh, 1609 const struct nlmsghdr *nlh,
1500 const struct nlattr * const attr[]) 1610 const struct nlattr * const attr[])
1501{ 1611{
1612 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl));
1502 const struct ip_set *set; 1613 const struct ip_set *set;
1503 struct sk_buff *skb2; 1614 struct sk_buff *skb2;
1504 struct nlmsghdr *nlh2; 1615 struct nlmsghdr *nlh2;
@@ -1508,7 +1619,7 @@ ip_set_header(struct sock *ctnl, struct sk_buff *skb,
1508 attr[IPSET_ATTR_SETNAME] == NULL)) 1619 attr[IPSET_ATTR_SETNAME] == NULL))
1509 return -IPSET_ERR_PROTOCOL; 1620 return -IPSET_ERR_PROTOCOL;
1510 1621
1511 set = find_set(nla_data(attr[IPSET_ATTR_SETNAME])); 1622 set = find_set(inst, nla_data(attr[IPSET_ATTR_SETNAME]));
1512 if (set == NULL) 1623 if (set == NULL)
1513 return -ENOENT; 1624 return -ENOENT;
1514 1625
@@ -1733,8 +1844,10 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
1733 unsigned int *op; 1844 unsigned int *op;
1734 void *data; 1845 void *data;
1735 int copylen = *len, ret = 0; 1846 int copylen = *len, ret = 0;
1847 struct net *net = sock_net(sk);
1848 struct ip_set_net *inst = ip_set_pernet(net);
1736 1849
1737 if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) 1850 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
1738 return -EPERM; 1851 return -EPERM;
1739 if (optval != SO_IP_SET) 1852 if (optval != SO_IP_SET)
1740 return -EBADF; 1853 return -EBADF;
@@ -1783,22 +1896,39 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
1783 } 1896 }
1784 req_get->set.name[IPSET_MAXNAMELEN - 1] = '\0'; 1897 req_get->set.name[IPSET_MAXNAMELEN - 1] = '\0';
1785 nfnl_lock(NFNL_SUBSYS_IPSET); 1898 nfnl_lock(NFNL_SUBSYS_IPSET);
1786 find_set_and_id(req_get->set.name, &id); 1899 find_set_and_id(inst, req_get->set.name, &id);
1787 req_get->set.index = id; 1900 req_get->set.index = id;
1788 nfnl_unlock(NFNL_SUBSYS_IPSET); 1901 nfnl_unlock(NFNL_SUBSYS_IPSET);
1789 goto copy; 1902 goto copy;
1790 } 1903 }
1904 case IP_SET_OP_GET_FNAME: {
1905 struct ip_set_req_get_set_family *req_get = data;
1906 ip_set_id_t id;
1907
1908 if (*len != sizeof(struct ip_set_req_get_set_family)) {
1909 ret = -EINVAL;
1910 goto done;
1911 }
1912 req_get->set.name[IPSET_MAXNAMELEN - 1] = '\0';
1913 nfnl_lock(NFNL_SUBSYS_IPSET);
1914 find_set_and_id(inst, req_get->set.name, &id);
1915 req_get->set.index = id;
1916 if (id != IPSET_INVALID_ID)
1917 req_get->family = nfnl_set(inst, id)->family;
1918 nfnl_unlock(NFNL_SUBSYS_IPSET);
1919 goto copy;
1920 }
1791 case IP_SET_OP_GET_BYINDEX: { 1921 case IP_SET_OP_GET_BYINDEX: {
1792 struct ip_set_req_get_set *req_get = data; 1922 struct ip_set_req_get_set *req_get = data;
1793 struct ip_set *set; 1923 struct ip_set *set;
1794 1924
1795 if (*len != sizeof(struct ip_set_req_get_set) || 1925 if (*len != sizeof(struct ip_set_req_get_set) ||
1796 req_get->set.index >= ip_set_max) { 1926 req_get->set.index >= inst->ip_set_max) {
1797 ret = -EINVAL; 1927 ret = -EINVAL;
1798 goto done; 1928 goto done;
1799 } 1929 }
1800 nfnl_lock(NFNL_SUBSYS_IPSET); 1930 nfnl_lock(NFNL_SUBSYS_IPSET);
1801 set = nfnl_set(req_get->set.index); 1931 set = nfnl_set(inst, req_get->set.index);
1802 strncpy(req_get->set.name, set ? set->name : "", 1932 strncpy(req_get->set.name, set ? set->name : "",
1803 IPSET_MAXNAMELEN); 1933 IPSET_MAXNAMELEN);
1804 nfnl_unlock(NFNL_SUBSYS_IPSET); 1934 nfnl_unlock(NFNL_SUBSYS_IPSET);
@@ -1827,49 +1957,82 @@ static struct nf_sockopt_ops so_set __read_mostly = {
1827 .owner = THIS_MODULE, 1957 .owner = THIS_MODULE,
1828}; 1958};
1829 1959
1830static int __init 1960static int __net_init
1831ip_set_init(void) 1961ip_set_net_init(struct net *net)
1832{ 1962{
1963 struct ip_set_net *inst = ip_set_pernet(net);
1964
1833 struct ip_set **list; 1965 struct ip_set **list;
1834 int ret;
1835 1966
1836 if (max_sets) 1967 inst->ip_set_max = max_sets ? max_sets : CONFIG_IP_SET_MAX;
1837 ip_set_max = max_sets; 1968 if (inst->ip_set_max >= IPSET_INVALID_ID)
1838 if (ip_set_max >= IPSET_INVALID_ID) 1969 inst->ip_set_max = IPSET_INVALID_ID - 1;
1839 ip_set_max = IPSET_INVALID_ID - 1;
1840 1970
1841 list = kzalloc(sizeof(struct ip_set *) * ip_set_max, GFP_KERNEL); 1971 list = kzalloc(sizeof(struct ip_set *) * inst->ip_set_max, GFP_KERNEL);
1842 if (!list) 1972 if (!list)
1843 return -ENOMEM; 1973 return -ENOMEM;
1974 inst->is_deleted = 0;
1975 rcu_assign_pointer(inst->ip_set_list, list);
1976 pr_notice("ip_set: protocol %u\n", IPSET_PROTOCOL);
1977 return 0;
1978}
1979
1980static void __net_exit
1981ip_set_net_exit(struct net *net)
1982{
1983 struct ip_set_net *inst = ip_set_pernet(net);
1984
1985 struct ip_set *set = NULL;
1986 ip_set_id_t i;
1987
1988 inst->is_deleted = 1; /* flag for ip_set_nfnl_put */
1989
1990 for (i = 0; i < inst->ip_set_max; i++) {
1991 set = nfnl_set(inst, i);
1992 if (set != NULL)
1993 ip_set_destroy_set(inst, i);
1994 }
1995 kfree(rcu_dereference_protected(inst->ip_set_list, 1));
1996}
1997
1998static struct pernet_operations ip_set_net_ops = {
1999 .init = ip_set_net_init,
2000 .exit = ip_set_net_exit,
2001 .id = &ip_set_net_id,
2002 .size = sizeof(struct ip_set_net)
2003};
2004
1844 2005
1845 rcu_assign_pointer(ip_set_list, list); 2006static int __init
1846 ret = nfnetlink_subsys_register(&ip_set_netlink_subsys); 2007ip_set_init(void)
2008{
2009 int ret = nfnetlink_subsys_register(&ip_set_netlink_subsys);
1847 if (ret != 0) { 2010 if (ret != 0) {
1848 pr_err("ip_set: cannot register with nfnetlink.\n"); 2011 pr_err("ip_set: cannot register with nfnetlink.\n");
1849 kfree(list);
1850 return ret; 2012 return ret;
1851 } 2013 }
1852 ret = nf_register_sockopt(&so_set); 2014 ret = nf_register_sockopt(&so_set);
1853 if (ret != 0) { 2015 if (ret != 0) {
1854 pr_err("SO_SET registry failed: %d\n", ret); 2016 pr_err("SO_SET registry failed: %d\n", ret);
1855 nfnetlink_subsys_unregister(&ip_set_netlink_subsys); 2017 nfnetlink_subsys_unregister(&ip_set_netlink_subsys);
1856 kfree(list);
1857 return ret; 2018 return ret;
1858 } 2019 }
1859 2020 ret = register_pernet_subsys(&ip_set_net_ops);
1860 pr_notice("ip_set: protocol %u\n", IPSET_PROTOCOL); 2021 if (ret) {
2022 pr_err("ip_set: cannot register pernet_subsys.\n");
2023 nf_unregister_sockopt(&so_set);
2024 nfnetlink_subsys_unregister(&ip_set_netlink_subsys);
2025 return ret;
2026 }
1861 return 0; 2027 return 0;
1862} 2028}
1863 2029
1864static void __exit 2030static void __exit
1865ip_set_fini(void) 2031ip_set_fini(void)
1866{ 2032{
1867 struct ip_set **list = rcu_dereference_protected(ip_set_list, 1); 2033 unregister_pernet_subsys(&ip_set_net_ops);
1868
1869 /* There can't be any existing set */
1870 nf_unregister_sockopt(&so_set); 2034 nf_unregister_sockopt(&so_set);
1871 nfnetlink_subsys_unregister(&ip_set_netlink_subsys); 2035 nfnetlink_subsys_unregister(&ip_set_netlink_subsys);
1872 kfree(list);
1873 pr_debug("these are the famous last words\n"); 2036 pr_debug("these are the famous last words\n");
1874} 2037}
1875 2038
diff --git a/net/netfilter/ipset/ip_set_getport.c b/net/netfilter/ipset/ip_set_getport.c
index dac156f819ac..29fb01ddff93 100644
--- a/net/netfilter/ipset/ip_set_getport.c
+++ b/net/netfilter/ipset/ip_set_getport.c
@@ -102,9 +102,25 @@ ip_set_get_ip4_port(const struct sk_buff *skb, bool src,
102 int protocol = iph->protocol; 102 int protocol = iph->protocol;
103 103
104 /* See comments at tcp_match in ip_tables.c */ 104 /* See comments at tcp_match in ip_tables.c */
105 if (protocol <= 0 || (ntohs(iph->frag_off) & IP_OFFSET)) 105 if (protocol <= 0)
106 return false; 106 return false;
107 107
108 if (ntohs(iph->frag_off) & IP_OFFSET)
109 switch (protocol) {
110 case IPPROTO_TCP:
111 case IPPROTO_SCTP:
112 case IPPROTO_UDP:
113 case IPPROTO_UDPLITE:
114 case IPPROTO_ICMP:
115 /* Port info not available for fragment offset > 0 */
116 return false;
117 default:
118 /* Other protocols doesn't have ports,
119 so we can match fragments */
120 *proto = protocol;
121 return true;
122 }
123
108 return get_port(skb, protocol, protooff, src, port, proto); 124 return get_port(skb, protocol, protooff, src, port, proto);
109} 125}
110EXPORT_SYMBOL_GPL(ip_set_get_ip4_port); 126EXPORT_SYMBOL_GPL(ip_set_get_ip4_port);
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
index 707bc520d629..6a80dbd30df7 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -15,8 +15,7 @@
15#define rcu_dereference_bh(p) rcu_dereference(p) 15#define rcu_dereference_bh(p) rcu_dereference(p)
16#endif 16#endif
17 17
18#define CONCAT(a, b) a##b 18#define rcu_dereference_bh_nfnl(p) rcu_dereference_bh_check(p, 1)
19#define TOKEN(a, b) CONCAT(a, b)
20 19
21/* Hashing which uses arrays to resolve clashing. The hash table is resized 20/* Hashing which uses arrays to resolve clashing. The hash table is resized
22 * (doubled) when searching becomes too long. 21 * (doubled) when searching becomes too long.
@@ -78,10 +77,14 @@ struct htable {
78 77
79#define hbucket(h, i) (&((h)->bucket[i])) 78#define hbucket(h, i) (&((h)->bucket[i]))
80 79
80#ifndef IPSET_NET_COUNT
81#define IPSET_NET_COUNT 1
82#endif
83
81/* Book-keeping of the prefixes added to the set */ 84/* Book-keeping of the prefixes added to the set */
82struct net_prefixes { 85struct net_prefixes {
83 u8 cidr; /* the different cidr values in the set */ 86 u32 nets[IPSET_NET_COUNT]; /* number of elements per cidr */
84 u32 nets; /* number of elements per cidr */ 87 u8 cidr[IPSET_NET_COUNT]; /* the different cidr values in the set */
85}; 88};
86 89
87/* Compute the hash table size */ 90/* Compute the hash table size */
@@ -114,23 +117,6 @@ htable_bits(u32 hashsize)
114 return bits; 117 return bits;
115} 118}
116 119
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 120static int
135hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize) 121hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize)
136{ 122{
@@ -156,30 +142,30 @@ hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize)
156} 142}
157 143
158#ifdef IP_SET_HASH_WITH_NETS 144#ifdef IP_SET_HASH_WITH_NETS
145#if IPSET_NET_COUNT > 1
146#define __CIDR(cidr, i) (cidr[i])
147#else
148#define __CIDR(cidr, i) (cidr)
149#endif
159#ifdef IP_SET_HASH_WITH_NETS_PACKED 150#ifdef IP_SET_HASH_WITH_NETS_PACKED
160/* When cidr is packed with nomatch, cidr - 1 is stored in the entry */ 151/* When cidr is packed with nomatch, cidr - 1 is stored in the entry */
161#define CIDR(cidr) (cidr + 1) 152#define CIDR(cidr, i) (__CIDR(cidr, i) + 1)
162#else 153#else
163#define CIDR(cidr) (cidr) 154#define CIDR(cidr, i) (__CIDR(cidr, i))
164#endif 155#endif
165 156
166#define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128) 157#define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128)
167 158
168#ifdef IP_SET_HASH_WITH_MULTI 159#ifdef IP_SET_HASH_WITH_MULTI
169#define NETS_LENGTH(family) (SET_HOST_MASK(family) + 1) 160#define NLEN(family) (SET_HOST_MASK(family) + 1)
170#else 161#else
171#define NETS_LENGTH(family) SET_HOST_MASK(family) 162#define NLEN(family) SET_HOST_MASK(family)
172#endif 163#endif
173 164
174#else 165#else
175#define NETS_LENGTH(family) 0 166#define NLEN(family) 0
176#endif /* IP_SET_HASH_WITH_NETS */ 167#endif /* IP_SET_HASH_WITH_NETS */
177 168
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 */ 169#endif /* _IP_SET_HASH_GEN_H */
184 170
185/* Family dependent templates */ 171/* Family dependent templates */
@@ -194,6 +180,8 @@ hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize)
194#undef mtype_data_next 180#undef mtype_data_next
195#undef mtype_elem 181#undef mtype_elem
196 182
183#undef mtype_ahash_destroy
184#undef mtype_ext_cleanup
197#undef mtype_add_cidr 185#undef mtype_add_cidr
198#undef mtype_del_cidr 186#undef mtype_del_cidr
199#undef mtype_ahash_memsize 187#undef mtype_ahash_memsize
@@ -220,41 +208,44 @@ hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize)
220 208
221#undef HKEY 209#undef HKEY
222 210
223#define mtype_data_equal TOKEN(MTYPE, _data_equal) 211#define mtype_data_equal IPSET_TOKEN(MTYPE, _data_equal)
224#ifdef IP_SET_HASH_WITH_NETS 212#ifdef IP_SET_HASH_WITH_NETS
225#define mtype_do_data_match TOKEN(MTYPE, _do_data_match) 213#define mtype_do_data_match IPSET_TOKEN(MTYPE, _do_data_match)
226#else 214#else
227#define mtype_do_data_match(d) 1 215#define mtype_do_data_match(d) 1
228#endif 216#endif
229#define mtype_data_set_flags TOKEN(MTYPE, _data_set_flags) 217#define mtype_data_set_flags IPSET_TOKEN(MTYPE, _data_set_flags)
230#define mtype_data_reset_flags TOKEN(MTYPE, _data_reset_flags) 218#define mtype_data_reset_elem IPSET_TOKEN(MTYPE, _data_reset_elem)
231#define mtype_data_netmask TOKEN(MTYPE, _data_netmask) 219#define mtype_data_reset_flags IPSET_TOKEN(MTYPE, _data_reset_flags)
232#define mtype_data_list TOKEN(MTYPE, _data_list) 220#define mtype_data_netmask IPSET_TOKEN(MTYPE, _data_netmask)
233#define mtype_data_next TOKEN(MTYPE, _data_next) 221#define mtype_data_list IPSET_TOKEN(MTYPE, _data_list)
234#define mtype_elem TOKEN(MTYPE, _elem) 222#define mtype_data_next IPSET_TOKEN(MTYPE, _data_next)
235#define mtype_add_cidr TOKEN(MTYPE, _add_cidr) 223#define mtype_elem IPSET_TOKEN(MTYPE, _elem)
236#define mtype_del_cidr TOKEN(MTYPE, _del_cidr) 224#define mtype_ahash_destroy IPSET_TOKEN(MTYPE, _ahash_destroy)
237#define mtype_ahash_memsize TOKEN(MTYPE, _ahash_memsize) 225#define mtype_ext_cleanup IPSET_TOKEN(MTYPE, _ext_cleanup)
238#define mtype_flush TOKEN(MTYPE, _flush) 226#define mtype_add_cidr IPSET_TOKEN(MTYPE, _add_cidr)
239#define mtype_destroy TOKEN(MTYPE, _destroy) 227#define mtype_del_cidr IPSET_TOKEN(MTYPE, _del_cidr)
240#define mtype_gc_init TOKEN(MTYPE, _gc_init) 228#define mtype_ahash_memsize IPSET_TOKEN(MTYPE, _ahash_memsize)
241#define mtype_same_set TOKEN(MTYPE, _same_set) 229#define mtype_flush IPSET_TOKEN(MTYPE, _flush)
242#define mtype_kadt TOKEN(MTYPE, _kadt) 230#define mtype_destroy IPSET_TOKEN(MTYPE, _destroy)
243#define mtype_uadt TOKEN(MTYPE, _uadt) 231#define mtype_gc_init IPSET_TOKEN(MTYPE, _gc_init)
232#define mtype_same_set IPSET_TOKEN(MTYPE, _same_set)
233#define mtype_kadt IPSET_TOKEN(MTYPE, _kadt)
234#define mtype_uadt IPSET_TOKEN(MTYPE, _uadt)
244#define mtype MTYPE 235#define mtype MTYPE
245 236
246#define mtype_elem TOKEN(MTYPE, _elem) 237#define mtype_elem IPSET_TOKEN(MTYPE, _elem)
247#define mtype_add TOKEN(MTYPE, _add) 238#define mtype_add IPSET_TOKEN(MTYPE, _add)
248#define mtype_del TOKEN(MTYPE, _del) 239#define mtype_del IPSET_TOKEN(MTYPE, _del)
249#define mtype_test_cidrs TOKEN(MTYPE, _test_cidrs) 240#define mtype_test_cidrs IPSET_TOKEN(MTYPE, _test_cidrs)
250#define mtype_test TOKEN(MTYPE, _test) 241#define mtype_test IPSET_TOKEN(MTYPE, _test)
251#define mtype_expire TOKEN(MTYPE, _expire) 242#define mtype_expire IPSET_TOKEN(MTYPE, _expire)
252#define mtype_resize TOKEN(MTYPE, _resize) 243#define mtype_resize IPSET_TOKEN(MTYPE, _resize)
253#define mtype_head TOKEN(MTYPE, _head) 244#define mtype_head IPSET_TOKEN(MTYPE, _head)
254#define mtype_list TOKEN(MTYPE, _list) 245#define mtype_list IPSET_TOKEN(MTYPE, _list)
255#define mtype_gc TOKEN(MTYPE, _gc) 246#define mtype_gc IPSET_TOKEN(MTYPE, _gc)
256#define mtype_variant TOKEN(MTYPE, _variant) 247#define mtype_variant IPSET_TOKEN(MTYPE, _variant)
257#define mtype_data_match TOKEN(MTYPE, _data_match) 248#define mtype_data_match IPSET_TOKEN(MTYPE, _data_match)
258 249
259#ifndef HKEY_DATALEN 250#ifndef HKEY_DATALEN
260#define HKEY_DATALEN sizeof(struct mtype_elem) 251#define HKEY_DATALEN sizeof(struct mtype_elem)
@@ -269,13 +260,10 @@ hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize)
269 260
270/* The generic hash structure */ 261/* The generic hash structure */
271struct htype { 262struct htype {
272 struct htable *table; /* the hash table */ 263 struct htable __rcu *table; /* the hash table */
273 u32 maxelem; /* max elements in the hash */ 264 u32 maxelem; /* max elements in the hash */
274 u32 elements; /* current element (vs timeout) */ 265 u32 elements; /* current element (vs timeout) */
275 u32 initval; /* random jhash init value */ 266 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 */ 267 struct timer_list gc; /* garbage collection when timeout enabled */
280 struct mtype_elem next; /* temporary storage for uadd */ 268 struct mtype_elem next; /* temporary storage for uadd */
281#ifdef IP_SET_HASH_WITH_MULTI 269#ifdef IP_SET_HASH_WITH_MULTI
@@ -297,49 +285,49 @@ struct htype {
297/* Network cidr size book keeping when the hash stores different 285/* Network cidr size book keeping when the hash stores different
298 * sized networks */ 286 * sized networks */
299static void 287static void
300mtype_add_cidr(struct htype *h, u8 cidr, u8 nets_length) 288mtype_add_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n)
301{ 289{
302 int i, j; 290 int i, j;
303 291
304 /* Add in increasing prefix order, so larger cidr first */ 292 /* Add in increasing prefix order, so larger cidr first */
305 for (i = 0, j = -1; i < nets_length && h->nets[i].nets; i++) { 293 for (i = 0, j = -1; i < nets_length && h->nets[i].nets[n]; i++) {
306 if (j != -1) 294 if (j != -1)
307 continue; 295 continue;
308 else if (h->nets[i].cidr < cidr) 296 else if (h->nets[i].cidr[n] < cidr)
309 j = i; 297 j = i;
310 else if (h->nets[i].cidr == cidr) { 298 else if (h->nets[i].cidr[n] == cidr) {
311 h->nets[i].nets++; 299 h->nets[i].nets[n]++;
312 return; 300 return;
313 } 301 }
314 } 302 }
315 if (j != -1) { 303 if (j != -1) {
316 for (; i > j; i--) { 304 for (; i > j; i--) {
317 h->nets[i].cidr = h->nets[i - 1].cidr; 305 h->nets[i].cidr[n] = h->nets[i - 1].cidr[n];
318 h->nets[i].nets = h->nets[i - 1].nets; 306 h->nets[i].nets[n] = h->nets[i - 1].nets[n];
319 } 307 }
320 } 308 }
321 h->nets[i].cidr = cidr; 309 h->nets[i].cidr[n] = cidr;
322 h->nets[i].nets = 1; 310 h->nets[i].nets[n] = 1;
323} 311}
324 312
325static void 313static void
326mtype_del_cidr(struct htype *h, u8 cidr, u8 nets_length) 314mtype_del_cidr(struct htype *h, u8 cidr, u8 nets_length, u8 n)
327{ 315{
328 u8 i, j, net_end = nets_length - 1; 316 u8 i, j, net_end = nets_length - 1;
329 317
330 for (i = 0; i < nets_length; i++) { 318 for (i = 0; i < nets_length; i++) {
331 if (h->nets[i].cidr != cidr) 319 if (h->nets[i].cidr[n] != cidr)
332 continue; 320 continue;
333 if (h->nets[i].nets > 1 || i == net_end || 321 if (h->nets[i].nets[n] > 1 || i == net_end ||
334 h->nets[i + 1].nets == 0) { 322 h->nets[i + 1].nets[n] == 0) {
335 h->nets[i].nets--; 323 h->nets[i].nets[n]--;
336 return; 324 return;
337 } 325 }
338 for (j = i; j < net_end && h->nets[j].nets; j++) { 326 for (j = i; j < net_end && h->nets[j].nets[n]; j++) {
339 h->nets[j].cidr = h->nets[j + 1].cidr; 327 h->nets[j].cidr[n] = h->nets[j + 1].cidr[n];
340 h->nets[j].nets = h->nets[j + 1].nets; 328 h->nets[j].nets[n] = h->nets[j + 1].nets[n];
341 } 329 }
342 h->nets[j].nets = 0; 330 h->nets[j].nets[n] = 0;
343 return; 331 return;
344 } 332 }
345} 333}
@@ -347,10 +335,10 @@ mtype_del_cidr(struct htype *h, u8 cidr, u8 nets_length)
347 335
348/* Calculate the actual memory size of the set data */ 336/* Calculate the actual memory size of the set data */
349static size_t 337static size_t
350mtype_ahash_memsize(const struct htype *h, u8 nets_length) 338mtype_ahash_memsize(const struct htype *h, const struct htable *t,
339 u8 nets_length, size_t dsize)
351{ 340{
352 u32 i; 341 u32 i;
353 struct htable *t = h->table;
354 size_t memsize = sizeof(*h) 342 size_t memsize = sizeof(*h)
355 + sizeof(*t) 343 + sizeof(*t)
356#ifdef IP_SET_HASH_WITH_NETS 344#ifdef IP_SET_HASH_WITH_NETS
@@ -359,35 +347,70 @@ mtype_ahash_memsize(const struct htype *h, u8 nets_length)
359 + jhash_size(t->htable_bits) * sizeof(struct hbucket); 347 + jhash_size(t->htable_bits) * sizeof(struct hbucket);
360 348
361 for (i = 0; i < jhash_size(t->htable_bits); i++) 349 for (i = 0; i < jhash_size(t->htable_bits); i++)
362 memsize += t->bucket[i].size * h->dsize; 350 memsize += t->bucket[i].size * dsize;
363 351
364 return memsize; 352 return memsize;
365} 353}
366 354
355/* Get the ith element from the array block n */
356#define ahash_data(n, i, dsize) \
357 ((struct mtype_elem *)((n)->value + ((i) * (dsize))))
358
359static void
360mtype_ext_cleanup(struct ip_set *set, struct hbucket *n)
361{
362 int i;
363
364 for (i = 0; i < n->pos; i++)
365 ip_set_ext_destroy(set, ahash_data(n, i, set->dsize));
366}
367
367/* Flush a hash type of set: destroy all elements */ 368/* Flush a hash type of set: destroy all elements */
368static void 369static void
369mtype_flush(struct ip_set *set) 370mtype_flush(struct ip_set *set)
370{ 371{
371 struct htype *h = set->data; 372 struct htype *h = set->data;
372 struct htable *t = h->table; 373 struct htable *t;
373 struct hbucket *n; 374 struct hbucket *n;
374 u32 i; 375 u32 i;
375 376
377 t = rcu_dereference_bh_nfnl(h->table);
376 for (i = 0; i < jhash_size(t->htable_bits); i++) { 378 for (i = 0; i < jhash_size(t->htable_bits); i++) {
377 n = hbucket(t, i); 379 n = hbucket(t, i);
378 if (n->size) { 380 if (n->size) {
381 if (set->extensions & IPSET_EXT_DESTROY)
382 mtype_ext_cleanup(set, n);
379 n->size = n->pos = 0; 383 n->size = n->pos = 0;
380 /* FIXME: use slab cache */ 384 /* FIXME: use slab cache */
381 kfree(n->value); 385 kfree(n->value);
382 } 386 }
383 } 387 }
384#ifdef IP_SET_HASH_WITH_NETS 388#ifdef IP_SET_HASH_WITH_NETS
385 memset(h->nets, 0, sizeof(struct net_prefixes) 389 memset(h->nets, 0, sizeof(struct net_prefixes) * NLEN(set->family));
386 * NETS_LENGTH(set->family));
387#endif 390#endif
388 h->elements = 0; 391 h->elements = 0;
389} 392}
390 393
394/* Destroy the hashtable part of the set */
395static void
396mtype_ahash_destroy(struct ip_set *set, struct htable *t, bool ext_destroy)
397{
398 struct hbucket *n;
399 u32 i;
400
401 for (i = 0; i < jhash_size(t->htable_bits); i++) {
402 n = hbucket(t, i);
403 if (n->size) {
404 if (set->extensions & IPSET_EXT_DESTROY && ext_destroy)
405 mtype_ext_cleanup(set, n);
406 /* FIXME: use slab cache */
407 kfree(n->value);
408 }
409 }
410
411 ip_set_free(t);
412}
413
391/* Destroy a hash type of set */ 414/* Destroy a hash type of set */
392static void 415static void
393mtype_destroy(struct ip_set *set) 416mtype_destroy(struct ip_set *set)
@@ -397,7 +420,7 @@ mtype_destroy(struct ip_set *set)
397 if (set->extensions & IPSET_EXT_TIMEOUT) 420 if (set->extensions & IPSET_EXT_TIMEOUT)
398 del_timer_sync(&h->gc); 421 del_timer_sync(&h->gc);
399 422
400 ahash_destroy(h->table); 423 mtype_ahash_destroy(set, rcu_dereference_bh_nfnl(h->table), true);
401#ifdef IP_SET_HASH_WITH_RBTREE 424#ifdef IP_SET_HASH_WITH_RBTREE
402 rbtree_destroy(&h->rbtree); 425 rbtree_destroy(&h->rbtree);
403#endif 426#endif
@@ -414,10 +437,10 @@ mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
414 init_timer(&h->gc); 437 init_timer(&h->gc);
415 h->gc.data = (unsigned long) set; 438 h->gc.data = (unsigned long) set;
416 h->gc.function = gc; 439 h->gc.function = gc;
417 h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ; 440 h->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
418 add_timer(&h->gc); 441 add_timer(&h->gc);
419 pr_debug("gc initialized, run in every %u\n", 442 pr_debug("gc initialized, run in every %u\n",
420 IPSET_GC_PERIOD(h->timeout)); 443 IPSET_GC_PERIOD(set->timeout));
421} 444}
422 445
423static bool 446static bool
@@ -428,37 +451,40 @@ mtype_same_set(const struct ip_set *a, const struct ip_set *b)
428 451
429 /* Resizing changes htable_bits, so we ignore it */ 452 /* Resizing changes htable_bits, so we ignore it */
430 return x->maxelem == y->maxelem && 453 return x->maxelem == y->maxelem &&
431 x->timeout == y->timeout && 454 a->timeout == b->timeout &&
432#ifdef IP_SET_HASH_WITH_NETMASK 455#ifdef IP_SET_HASH_WITH_NETMASK
433 x->netmask == y->netmask && 456 x->netmask == y->netmask &&
434#endif 457#endif
435 a->extensions == b->extensions; 458 a->extensions == b->extensions;
436} 459}
437 460
438/* Get the ith element from the array block n */
439#define ahash_data(n, i, dsize) \
440 ((struct mtype_elem *)((n)->value + ((i) * (dsize))))
441
442/* Delete expired elements from the hashtable */ 461/* Delete expired elements from the hashtable */
443static void 462static void
444mtype_expire(struct htype *h, u8 nets_length, size_t dsize) 463mtype_expire(struct ip_set *set, struct htype *h, u8 nets_length, size_t dsize)
445{ 464{
446 struct htable *t = h->table; 465 struct htable *t;
447 struct hbucket *n; 466 struct hbucket *n;
448 struct mtype_elem *data; 467 struct mtype_elem *data;
449 u32 i; 468 u32 i;
450 int j; 469 int j;
470#ifdef IP_SET_HASH_WITH_NETS
471 u8 k;
472#endif
451 473
474 rcu_read_lock_bh();
475 t = rcu_dereference_bh(h->table);
452 for (i = 0; i < jhash_size(t->htable_bits); i++) { 476 for (i = 0; i < jhash_size(t->htable_bits); i++) {
453 n = hbucket(t, i); 477 n = hbucket(t, i);
454 for (j = 0; j < n->pos; j++) { 478 for (j = 0; j < n->pos; j++) {
455 data = ahash_data(n, j, dsize); 479 data = ahash_data(n, j, dsize);
456 if (ip_set_timeout_expired(ext_timeout(data, h))) { 480 if (ip_set_timeout_expired(ext_timeout(data, set))) {
457 pr_debug("expired %u/%u\n", i, j); 481 pr_debug("expired %u/%u\n", i, j);
458#ifdef IP_SET_HASH_WITH_NETS 482#ifdef IP_SET_HASH_WITH_NETS
459 mtype_del_cidr(h, CIDR(data->cidr), 483 for (k = 0; k < IPSET_NET_COUNT; k++)
460 nets_length); 484 mtype_del_cidr(h, CIDR(data->cidr, k),
485 nets_length, k);
461#endif 486#endif
487 ip_set_ext_destroy(set, data);
462 if (j != n->pos - 1) 488 if (j != n->pos - 1)
463 /* Not last one */ 489 /* Not last one */
464 memcpy(data, 490 memcpy(data,
@@ -481,6 +507,7 @@ mtype_expire(struct htype *h, u8 nets_length, size_t dsize)
481 n->value = tmp; 507 n->value = tmp;
482 } 508 }
483 } 509 }
510 rcu_read_unlock_bh();
484} 511}
485 512
486static void 513static void
@@ -491,10 +518,10 @@ mtype_gc(unsigned long ul_set)
491 518
492 pr_debug("called\n"); 519 pr_debug("called\n");
493 write_lock_bh(&set->lock); 520 write_lock_bh(&set->lock);
494 mtype_expire(h, NETS_LENGTH(set->family), h->dsize); 521 mtype_expire(set, h, NLEN(set->family), set->dsize);
495 write_unlock_bh(&set->lock); 522 write_unlock_bh(&set->lock);
496 523
497 h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ; 524 h->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
498 add_timer(&h->gc); 525 add_timer(&h->gc);
499} 526}
500 527
@@ -505,7 +532,7 @@ static int
505mtype_resize(struct ip_set *set, bool retried) 532mtype_resize(struct ip_set *set, bool retried)
506{ 533{
507 struct htype *h = set->data; 534 struct htype *h = set->data;
508 struct htable *t, *orig = h->table; 535 struct htable *t, *orig = rcu_dereference_bh_nfnl(h->table);
509 u8 htable_bits = orig->htable_bits; 536 u8 htable_bits = orig->htable_bits;
510#ifdef IP_SET_HASH_WITH_NETS 537#ifdef IP_SET_HASH_WITH_NETS
511 u8 flags; 538 u8 flags;
@@ -520,8 +547,7 @@ mtype_resize(struct ip_set *set, bool retried)
520 if (SET_WITH_TIMEOUT(set) && !retried) { 547 if (SET_WITH_TIMEOUT(set) && !retried) {
521 i = h->elements; 548 i = h->elements;
522 write_lock_bh(&set->lock); 549 write_lock_bh(&set->lock);
523 mtype_expire(set->data, NETS_LENGTH(set->family), 550 mtype_expire(set, set->data, NLEN(set->family), set->dsize);
524 h->dsize);
525 write_unlock_bh(&set->lock); 551 write_unlock_bh(&set->lock);
526 if (h->elements < i) 552 if (h->elements < i)
527 return 0; 553 return 0;
@@ -548,25 +574,25 @@ retry:
548 for (i = 0; i < jhash_size(orig->htable_bits); i++) { 574 for (i = 0; i < jhash_size(orig->htable_bits); i++) {
549 n = hbucket(orig, i); 575 n = hbucket(orig, i);
550 for (j = 0; j < n->pos; j++) { 576 for (j = 0; j < n->pos; j++) {
551 data = ahash_data(n, j, h->dsize); 577 data = ahash_data(n, j, set->dsize);
552#ifdef IP_SET_HASH_WITH_NETS 578#ifdef IP_SET_HASH_WITH_NETS
553 flags = 0; 579 flags = 0;
554 mtype_data_reset_flags(data, &flags); 580 mtype_data_reset_flags(data, &flags);
555#endif 581#endif
556 m = hbucket(t, HKEY(data, h->initval, htable_bits)); 582 m = hbucket(t, HKEY(data, h->initval, htable_bits));
557 ret = hbucket_elem_add(m, AHASH_MAX(h), h->dsize); 583 ret = hbucket_elem_add(m, AHASH_MAX(h), set->dsize);
558 if (ret < 0) { 584 if (ret < 0) {
559#ifdef IP_SET_HASH_WITH_NETS 585#ifdef IP_SET_HASH_WITH_NETS
560 mtype_data_reset_flags(data, &flags); 586 mtype_data_reset_flags(data, &flags);
561#endif 587#endif
562 read_unlock_bh(&set->lock); 588 read_unlock_bh(&set->lock);
563 ahash_destroy(t); 589 mtype_ahash_destroy(set, t, false);
564 if (ret == -EAGAIN) 590 if (ret == -EAGAIN)
565 goto retry; 591 goto retry;
566 return ret; 592 return ret;
567 } 593 }
568 d = ahash_data(m, m->pos++, h->dsize); 594 d = ahash_data(m, m->pos++, set->dsize);
569 memcpy(d, data, h->dsize); 595 memcpy(d, data, set->dsize);
570#ifdef IP_SET_HASH_WITH_NETS 596#ifdef IP_SET_HASH_WITH_NETS
571 mtype_data_reset_flags(d, &flags); 597 mtype_data_reset_flags(d, &flags);
572#endif 598#endif
@@ -581,7 +607,7 @@ retry:
581 607
582 pr_debug("set %s resized from %u (%p) to %u (%p)\n", set->name, 608 pr_debug("set %s resized from %u (%p) to %u (%p)\n", set->name,
583 orig->htable_bits, orig, t->htable_bits, t); 609 orig->htable_bits, orig, t->htable_bits, t);
584 ahash_destroy(orig); 610 mtype_ahash_destroy(set, orig, false);
585 611
586 return 0; 612 return 0;
587} 613}
@@ -604,7 +630,7 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
604 630
605 if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem) 631 if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem)
606 /* FIXME: when set is full, we slow down here */ 632 /* FIXME: when set is full, we slow down here */
607 mtype_expire(h, NETS_LENGTH(set->family), h->dsize); 633 mtype_expire(set, h, NLEN(set->family), set->dsize);
608 634
609 if (h->elements >= h->maxelem) { 635 if (h->elements >= h->maxelem) {
610 if (net_ratelimit()) 636 if (net_ratelimit())
@@ -618,11 +644,11 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
618 key = HKEY(value, h->initval, t->htable_bits); 644 key = HKEY(value, h->initval, t->htable_bits);
619 n = hbucket(t, key); 645 n = hbucket(t, key);
620 for (i = 0; i < n->pos; i++) { 646 for (i = 0; i < n->pos; i++) {
621 data = ahash_data(n, i, h->dsize); 647 data = ahash_data(n, i, set->dsize);
622 if (mtype_data_equal(data, d, &multi)) { 648 if (mtype_data_equal(data, d, &multi)) {
623 if (flag_exist || 649 if (flag_exist ||
624 (SET_WITH_TIMEOUT(set) && 650 (SET_WITH_TIMEOUT(set) &&
625 ip_set_timeout_expired(ext_timeout(data, h)))) { 651 ip_set_timeout_expired(ext_timeout(data, set)))) {
626 /* Just the extensions could be overwritten */ 652 /* Just the extensions could be overwritten */
627 j = i; 653 j = i;
628 goto reuse_slot; 654 goto reuse_slot;
@@ -633,30 +659,37 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
633 } 659 }
634 /* Reuse first timed out entry */ 660 /* Reuse first timed out entry */
635 if (SET_WITH_TIMEOUT(set) && 661 if (SET_WITH_TIMEOUT(set) &&
636 ip_set_timeout_expired(ext_timeout(data, h)) && 662 ip_set_timeout_expired(ext_timeout(data, set)) &&
637 j != AHASH_MAX(h) + 1) 663 j != AHASH_MAX(h) + 1)
638 j = i; 664 j = i;
639 } 665 }
640reuse_slot: 666reuse_slot:
641 if (j != AHASH_MAX(h) + 1) { 667 if (j != AHASH_MAX(h) + 1) {
642 /* Fill out reused slot */ 668 /* Fill out reused slot */
643 data = ahash_data(n, j, h->dsize); 669 data = ahash_data(n, j, set->dsize);
644#ifdef IP_SET_HASH_WITH_NETS 670#ifdef IP_SET_HASH_WITH_NETS
645 mtype_del_cidr(h, CIDR(data->cidr), NETS_LENGTH(set->family)); 671 for (i = 0; i < IPSET_NET_COUNT; i++) {
646 mtype_add_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family)); 672 mtype_del_cidr(h, CIDR(data->cidr, i),
673 NLEN(set->family), i);
674 mtype_add_cidr(h, CIDR(d->cidr, i),
675 NLEN(set->family), i);
676 }
647#endif 677#endif
678 ip_set_ext_destroy(set, data);
648 } else { 679 } else {
649 /* Use/create a new slot */ 680 /* Use/create a new slot */
650 TUNE_AHASH_MAX(h, multi); 681 TUNE_AHASH_MAX(h, multi);
651 ret = hbucket_elem_add(n, AHASH_MAX(h), h->dsize); 682 ret = hbucket_elem_add(n, AHASH_MAX(h), set->dsize);
652 if (ret != 0) { 683 if (ret != 0) {
653 if (ret == -EAGAIN) 684 if (ret == -EAGAIN)
654 mtype_data_next(&h->next, d); 685 mtype_data_next(&h->next, d);
655 goto out; 686 goto out;
656 } 687 }
657 data = ahash_data(n, n->pos++, h->dsize); 688 data = ahash_data(n, n->pos++, set->dsize);
658#ifdef IP_SET_HASH_WITH_NETS 689#ifdef IP_SET_HASH_WITH_NETS
659 mtype_add_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family)); 690 for (i = 0; i < IPSET_NET_COUNT; i++)
691 mtype_add_cidr(h, CIDR(d->cidr, i), NLEN(set->family),
692 i);
660#endif 693#endif
661 h->elements++; 694 h->elements++;
662 } 695 }
@@ -665,9 +698,11 @@ reuse_slot:
665 mtype_data_set_flags(data, flags); 698 mtype_data_set_flags(data, flags);
666#endif 699#endif
667 if (SET_WITH_TIMEOUT(set)) 700 if (SET_WITH_TIMEOUT(set))
668 ip_set_timeout_set(ext_timeout(data, h), ext->timeout); 701 ip_set_timeout_set(ext_timeout(data, set), ext->timeout);
669 if (SET_WITH_COUNTER(set)) 702 if (SET_WITH_COUNTER(set))
670 ip_set_init_counter(ext_counter(data, h), ext); 703 ip_set_init_counter(ext_counter(data, set), ext);
704 if (SET_WITH_COMMENT(set))
705 ip_set_init_comment(ext_comment(data, set), ext);
671 706
672out: 707out:
673 rcu_read_unlock_bh(); 708 rcu_read_unlock_bh();
@@ -682,47 +717,60 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext,
682 struct ip_set_ext *mext, u32 flags) 717 struct ip_set_ext *mext, u32 flags)
683{ 718{
684 struct htype *h = set->data; 719 struct htype *h = set->data;
685 struct htable *t = h->table; 720 struct htable *t;
686 const struct mtype_elem *d = value; 721 const struct mtype_elem *d = value;
687 struct mtype_elem *data; 722 struct mtype_elem *data;
688 struct hbucket *n; 723 struct hbucket *n;
689 int i; 724 int i, ret = -IPSET_ERR_EXIST;
725#ifdef IP_SET_HASH_WITH_NETS
726 u8 j;
727#endif
690 u32 key, multi = 0; 728 u32 key, multi = 0;
691 729
730 rcu_read_lock_bh();
731 t = rcu_dereference_bh(h->table);
692 key = HKEY(value, h->initval, t->htable_bits); 732 key = HKEY(value, h->initval, t->htable_bits);
693 n = hbucket(t, key); 733 n = hbucket(t, key);
694 for (i = 0; i < n->pos; i++) { 734 for (i = 0; i < n->pos; i++) {
695 data = ahash_data(n, i, h->dsize); 735 data = ahash_data(n, i, set->dsize);
696 if (!mtype_data_equal(data, d, &multi)) 736 if (!mtype_data_equal(data, d, &multi))
697 continue; 737 continue;
698 if (SET_WITH_TIMEOUT(set) && 738 if (SET_WITH_TIMEOUT(set) &&
699 ip_set_timeout_expired(ext_timeout(data, h))) 739 ip_set_timeout_expired(ext_timeout(data, set)))
700 return -IPSET_ERR_EXIST; 740 goto out;
701 if (i != n->pos - 1) 741 if (i != n->pos - 1)
702 /* Not last one */ 742 /* Not last one */
703 memcpy(data, ahash_data(n, n->pos - 1, h->dsize), 743 memcpy(data, ahash_data(n, n->pos - 1, set->dsize),
704 h->dsize); 744 set->dsize);
705 745
706 n->pos--; 746 n->pos--;
707 h->elements--; 747 h->elements--;
708#ifdef IP_SET_HASH_WITH_NETS 748#ifdef IP_SET_HASH_WITH_NETS
709 mtype_del_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family)); 749 for (j = 0; j < IPSET_NET_COUNT; j++)
750 mtype_del_cidr(h, CIDR(d->cidr, j), NLEN(set->family),
751 j);
710#endif 752#endif
753 ip_set_ext_destroy(set, data);
711 if (n->pos + AHASH_INIT_SIZE < n->size) { 754 if (n->pos + AHASH_INIT_SIZE < n->size) {
712 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE) 755 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
713 * h->dsize, 756 * set->dsize,
714 GFP_ATOMIC); 757 GFP_ATOMIC);
715 if (!tmp) 758 if (!tmp) {
716 return 0; 759 ret = 0;
760 goto out;
761 }
717 n->size -= AHASH_INIT_SIZE; 762 n->size -= AHASH_INIT_SIZE;
718 memcpy(tmp, n->value, n->size * h->dsize); 763 memcpy(tmp, n->value, n->size * set->dsize);
719 kfree(n->value); 764 kfree(n->value);
720 n->value = tmp; 765 n->value = tmp;
721 } 766 }
722 return 0; 767 ret = 0;
768 goto out;
723 } 769 }
724 770
725 return -IPSET_ERR_EXIST; 771out:
772 rcu_read_unlock_bh();
773 return ret;
726} 774}
727 775
728static inline int 776static inline int
@@ -730,8 +778,7 @@ mtype_data_match(struct mtype_elem *data, const struct ip_set_ext *ext,
730 struct ip_set_ext *mext, struct ip_set *set, u32 flags) 778 struct ip_set_ext *mext, struct ip_set *set, u32 flags)
731{ 779{
732 if (SET_WITH_COUNTER(set)) 780 if (SET_WITH_COUNTER(set))
733 ip_set_update_counter(ext_counter(data, 781 ip_set_update_counter(ext_counter(data, set),
734 (struct htype *)(set->data)),
735 ext, mext, flags); 782 ext, mext, flags);
736 return mtype_do_data_match(data); 783 return mtype_do_data_match(data);
737} 784}
@@ -745,25 +792,38 @@ mtype_test_cidrs(struct ip_set *set, struct mtype_elem *d,
745 struct ip_set_ext *mext, u32 flags) 792 struct ip_set_ext *mext, u32 flags)
746{ 793{
747 struct htype *h = set->data; 794 struct htype *h = set->data;
748 struct htable *t = h->table; 795 struct htable *t = rcu_dereference_bh(h->table);
749 struct hbucket *n; 796 struct hbucket *n;
750 struct mtype_elem *data; 797 struct mtype_elem *data;
798#if IPSET_NET_COUNT == 2
799 struct mtype_elem orig = *d;
800 int i, j = 0, k;
801#else
751 int i, j = 0; 802 int i, j = 0;
803#endif
752 u32 key, multi = 0; 804 u32 key, multi = 0;
753 u8 nets_length = NETS_LENGTH(set->family); 805 u8 nets_length = NLEN(set->family);
754 806
755 pr_debug("test by nets\n"); 807 pr_debug("test by nets\n");
756 for (; j < nets_length && h->nets[j].nets && !multi; j++) { 808 for (; j < nets_length && h->nets[j].nets[0] && !multi; j++) {
757 mtype_data_netmask(d, h->nets[j].cidr); 809#if IPSET_NET_COUNT == 2
810 mtype_data_reset_elem(d, &orig);
811 mtype_data_netmask(d, h->nets[j].cidr[0], false);
812 for (k = 0; k < nets_length && h->nets[k].nets[1] && !multi;
813 k++) {
814 mtype_data_netmask(d, h->nets[k].cidr[1], true);
815#else
816 mtype_data_netmask(d, h->nets[j].cidr[0]);
817#endif
758 key = HKEY(d, h->initval, t->htable_bits); 818 key = HKEY(d, h->initval, t->htable_bits);
759 n = hbucket(t, key); 819 n = hbucket(t, key);
760 for (i = 0; i < n->pos; i++) { 820 for (i = 0; i < n->pos; i++) {
761 data = ahash_data(n, i, h->dsize); 821 data = ahash_data(n, i, set->dsize);
762 if (!mtype_data_equal(data, d, &multi)) 822 if (!mtype_data_equal(data, d, &multi))
763 continue; 823 continue;
764 if (SET_WITH_TIMEOUT(set)) { 824 if (SET_WITH_TIMEOUT(set)) {
765 if (!ip_set_timeout_expired( 825 if (!ip_set_timeout_expired(
766 ext_timeout(data, h))) 826 ext_timeout(data, set)))
767 return mtype_data_match(data, ext, 827 return mtype_data_match(data, ext,
768 mext, set, 828 mext, set,
769 flags); 829 flags);
@@ -774,6 +834,9 @@ mtype_test_cidrs(struct ip_set *set, struct mtype_elem *d,
774 return mtype_data_match(data, ext, 834 return mtype_data_match(data, ext,
775 mext, set, flags); 835 mext, set, flags);
776 } 836 }
837#if IPSET_NET_COUNT == 2
838 }
839#endif
777 } 840 }
778 return 0; 841 return 0;
779} 842}
@@ -785,30 +848,41 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext,
785 struct ip_set_ext *mext, u32 flags) 848 struct ip_set_ext *mext, u32 flags)
786{ 849{
787 struct htype *h = set->data; 850 struct htype *h = set->data;
788 struct htable *t = h->table; 851 struct htable *t;
789 struct mtype_elem *d = value; 852 struct mtype_elem *d = value;
790 struct hbucket *n; 853 struct hbucket *n;
791 struct mtype_elem *data; 854 struct mtype_elem *data;
792 int i; 855 int i, ret = 0;
793 u32 key, multi = 0; 856 u32 key, multi = 0;
794 857
858 rcu_read_lock_bh();
859 t = rcu_dereference_bh(h->table);
795#ifdef IP_SET_HASH_WITH_NETS 860#ifdef IP_SET_HASH_WITH_NETS
796 /* If we test an IP address and not a network address, 861 /* If we test an IP address and not a network address,
797 * try all possible network sizes */ 862 * try all possible network sizes */
798 if (CIDR(d->cidr) == SET_HOST_MASK(set->family)) 863 for (i = 0; i < IPSET_NET_COUNT; i++)
799 return mtype_test_cidrs(set, d, ext, mext, flags); 864 if (CIDR(d->cidr, i) != SET_HOST_MASK(set->family))
865 break;
866 if (i == IPSET_NET_COUNT) {
867 ret = mtype_test_cidrs(set, d, ext, mext, flags);
868 goto out;
869 }
800#endif 870#endif
801 871
802 key = HKEY(d, h->initval, t->htable_bits); 872 key = HKEY(d, h->initval, t->htable_bits);
803 n = hbucket(t, key); 873 n = hbucket(t, key);
804 for (i = 0; i < n->pos; i++) { 874 for (i = 0; i < n->pos; i++) {
805 data = ahash_data(n, i, h->dsize); 875 data = ahash_data(n, i, set->dsize);
806 if (mtype_data_equal(data, d, &multi) && 876 if (mtype_data_equal(data, d, &multi) &&
807 !(SET_WITH_TIMEOUT(set) && 877 !(SET_WITH_TIMEOUT(set) &&
808 ip_set_timeout_expired(ext_timeout(data, h)))) 878 ip_set_timeout_expired(ext_timeout(data, set)))) {
809 return mtype_data_match(data, ext, mext, set, flags); 879 ret = mtype_data_match(data, ext, mext, set, flags);
880 goto out;
881 }
810 } 882 }
811 return 0; 883out:
884 rcu_read_unlock_bh();
885 return ret;
812} 886}
813 887
814/* Reply a HEADER request: fill out the header part of the set */ 888/* Reply a HEADER request: fill out the header part of the set */
@@ -816,18 +890,18 @@ static int
816mtype_head(struct ip_set *set, struct sk_buff *skb) 890mtype_head(struct ip_set *set, struct sk_buff *skb)
817{ 891{
818 const struct htype *h = set->data; 892 const struct htype *h = set->data;
893 const struct htable *t;
819 struct nlattr *nested; 894 struct nlattr *nested;
820 size_t memsize; 895 size_t memsize;
821 896
822 read_lock_bh(&set->lock); 897 t = rcu_dereference_bh_nfnl(h->table);
823 memsize = mtype_ahash_memsize(h, NETS_LENGTH(set->family)); 898 memsize = mtype_ahash_memsize(h, t, NLEN(set->family), set->dsize);
824 read_unlock_bh(&set->lock);
825 899
826 nested = ipset_nest_start(skb, IPSET_ATTR_DATA); 900 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
827 if (!nested) 901 if (!nested)
828 goto nla_put_failure; 902 goto nla_put_failure;
829 if (nla_put_net32(skb, IPSET_ATTR_HASHSIZE, 903 if (nla_put_net32(skb, IPSET_ATTR_HASHSIZE,
830 htonl(jhash_size(h->table->htable_bits))) || 904 htonl(jhash_size(t->htable_bits))) ||
831 nla_put_net32(skb, IPSET_ATTR_MAXELEM, htonl(h->maxelem))) 905 nla_put_net32(skb, IPSET_ATTR_MAXELEM, htonl(h->maxelem)))
832 goto nla_put_failure; 906 goto nla_put_failure;
833#ifdef IP_SET_HASH_WITH_NETMASK 907#ifdef IP_SET_HASH_WITH_NETMASK
@@ -836,12 +910,9 @@ mtype_head(struct ip_set *set, struct sk_buff *skb)
836 goto nla_put_failure; 910 goto nla_put_failure;
837#endif 911#endif
838 if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || 912 if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
839 nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) || 913 nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)))
840 ((set->extensions & IPSET_EXT_TIMEOUT) && 914 goto nla_put_failure;
841 nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout))) || 915 if (unlikely(ip_set_put_flags(skb, set)))
842 ((set->extensions & IPSET_EXT_COUNTER) &&
843 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS,
844 htonl(IPSET_FLAG_WITH_COUNTERS))))
845 goto nla_put_failure; 916 goto nla_put_failure;
846 ipset_nest_end(skb, nested); 917 ipset_nest_end(skb, nested);
847 918
@@ -856,7 +927,7 @@ mtype_list(const struct ip_set *set,
856 struct sk_buff *skb, struct netlink_callback *cb) 927 struct sk_buff *skb, struct netlink_callback *cb)
857{ 928{
858 const struct htype *h = set->data; 929 const struct htype *h = set->data;
859 const struct htable *t = h->table; 930 const struct htable *t = rcu_dereference_bh_nfnl(h->table);
860 struct nlattr *atd, *nested; 931 struct nlattr *atd, *nested;
861 const struct hbucket *n; 932 const struct hbucket *n;
862 const struct mtype_elem *e; 933 const struct mtype_elem *e;
@@ -874,9 +945,9 @@ mtype_list(const struct ip_set *set,
874 n = hbucket(t, cb->args[2]); 945 n = hbucket(t, cb->args[2]);
875 pr_debug("cb->args[2]: %lu, t %p n %p\n", cb->args[2], t, n); 946 pr_debug("cb->args[2]: %lu, t %p n %p\n", cb->args[2], t, n);
876 for (i = 0; i < n->pos; i++) { 947 for (i = 0; i < n->pos; i++) {
877 e = ahash_data(n, i, h->dsize); 948 e = ahash_data(n, i, set->dsize);
878 if (SET_WITH_TIMEOUT(set) && 949 if (SET_WITH_TIMEOUT(set) &&
879 ip_set_timeout_expired(ext_timeout(e, h))) 950 ip_set_timeout_expired(ext_timeout(e, set)))
880 continue; 951 continue;
881 pr_debug("list hash %lu hbucket %p i %u, data %p\n", 952 pr_debug("list hash %lu hbucket %p i %u, data %p\n",
882 cb->args[2], n, i, e); 953 cb->args[2], n, i, e);
@@ -890,13 +961,7 @@ mtype_list(const struct ip_set *set,
890 } 961 }
891 if (mtype_data_list(skb, e)) 962 if (mtype_data_list(skb, e))
892 goto nla_put_failure; 963 goto nla_put_failure;
893 if (SET_WITH_TIMEOUT(set) && 964 if (ip_set_put_extensions(skb, set, e, true))
894 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
895 htonl(ip_set_timeout_get(
896 ext_timeout(e, h)))))
897 goto nla_put_failure;
898 if (SET_WITH_COUNTER(set) &&
899 ip_set_put_counter(skb, ext_counter(e, h)))
900 goto nla_put_failure; 965 goto nla_put_failure;
901 ipset_nest_end(skb, nested); 966 ipset_nest_end(skb, nested);
902 } 967 }
@@ -909,24 +974,24 @@ mtype_list(const struct ip_set *set,
909 974
910nla_put_failure: 975nla_put_failure:
911 nlmsg_trim(skb, incomplete); 976 nlmsg_trim(skb, incomplete);
912 ipset_nest_end(skb, atd);
913 if (unlikely(first == cb->args[2])) { 977 if (unlikely(first == cb->args[2])) {
914 pr_warning("Can't list set %s: one bucket does not fit into " 978 pr_warning("Can't list set %s: one bucket does not fit into "
915 "a message. Please report it!\n", set->name); 979 "a message. Please report it!\n", set->name);
916 cb->args[2] = 0; 980 cb->args[2] = 0;
917 return -EMSGSIZE; 981 return -EMSGSIZE;
918 } 982 }
983 ipset_nest_end(skb, atd);
919 return 0; 984 return 0;
920} 985}
921 986
922static int 987static int
923TOKEN(MTYPE, _kadt)(struct ip_set *set, const struct sk_buff *skb, 988IPSET_TOKEN(MTYPE, _kadt)(struct ip_set *set, const struct sk_buff *skb,
924 const struct xt_action_param *par, 989 const struct xt_action_param *par,
925 enum ipset_adt adt, struct ip_set_adt_opt *opt); 990 enum ipset_adt adt, struct ip_set_adt_opt *opt);
926 991
927static int 992static int
928TOKEN(MTYPE, _uadt)(struct ip_set *set, struct nlattr *tb[], 993IPSET_TOKEN(MTYPE, _uadt)(struct ip_set *set, struct nlattr *tb[],
929 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried); 994 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried);
930 995
931static const struct ip_set_type_variant mtype_variant = { 996static const struct ip_set_type_variant mtype_variant = {
932 .kadt = mtype_kadt, 997 .kadt = mtype_kadt,
@@ -946,16 +1011,17 @@ static const struct ip_set_type_variant mtype_variant = {
946 1011
947#ifdef IP_SET_EMIT_CREATE 1012#ifdef IP_SET_EMIT_CREATE
948static int 1013static int
949TOKEN(HTYPE, _create)(struct ip_set *set, struct nlattr *tb[], u32 flags) 1014IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set,
1015 struct nlattr *tb[], u32 flags)
950{ 1016{
951 u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM; 1017 u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
952 u32 cadt_flags = 0;
953 u8 hbits; 1018 u8 hbits;
954#ifdef IP_SET_HASH_WITH_NETMASK 1019#ifdef IP_SET_HASH_WITH_NETMASK
955 u8 netmask; 1020 u8 netmask;
956#endif 1021#endif
957 size_t hsize; 1022 size_t hsize;
958 struct HTYPE *h; 1023 struct HTYPE *h;
1024 struct htable *t;
959 1025
960 if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6)) 1026 if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
961 return -IPSET_ERR_INVALID_FAMILY; 1027 return -IPSET_ERR_INVALID_FAMILY;
@@ -1005,7 +1071,7 @@ TOKEN(HTYPE, _create)(struct ip_set *set, struct nlattr *tb[], u32 flags)
1005 h->netmask = netmask; 1071 h->netmask = netmask;
1006#endif 1072#endif
1007 get_random_bytes(&h->initval, sizeof(h->initval)); 1073 get_random_bytes(&h->initval, sizeof(h->initval));
1008 h->timeout = IPSET_NO_TIMEOUT; 1074 set->timeout = IPSET_NO_TIMEOUT;
1009 1075
1010 hbits = htable_bits(hashsize); 1076 hbits = htable_bits(hashsize);
1011 hsize = htable_size(hbits); 1077 hsize = htable_size(hbits);
@@ -1013,91 +1079,37 @@ TOKEN(HTYPE, _create)(struct ip_set *set, struct nlattr *tb[], u32 flags)
1013 kfree(h); 1079 kfree(h);
1014 return -ENOMEM; 1080 return -ENOMEM;
1015 } 1081 }
1016 h->table = ip_set_alloc(hsize); 1082 t = ip_set_alloc(hsize);
1017 if (!h->table) { 1083 if (!t) {
1018 kfree(h); 1084 kfree(h);
1019 return -ENOMEM; 1085 return -ENOMEM;
1020 } 1086 }
1021 h->table->htable_bits = hbits; 1087 t->htable_bits = hbits;
1088 rcu_assign_pointer(h->table, t);
1022 1089
1023 set->data = h; 1090 set->data = h;
1024 if (set->family == NFPROTO_IPV4) 1091 if (set->family == NFPROTO_IPV4) {
1025 set->variant = &TOKEN(HTYPE, 4_variant); 1092 set->variant = &IPSET_TOKEN(HTYPE, 4_variant);
1026 else 1093 set->dsize = ip_set_elem_len(set, tb,
1027 set->variant = &TOKEN(HTYPE, 6_variant); 1094 sizeof(struct IPSET_TOKEN(HTYPE, 4_elem)));
1028
1029 if (tb[IPSET_ATTR_CADT_FLAGS])
1030 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
1031 if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) {
1032 set->extensions |= IPSET_EXT_COUNTER;
1033 if (tb[IPSET_ATTR_TIMEOUT]) {
1034 h->timeout =
1035 ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
1036 set->extensions |= IPSET_EXT_TIMEOUT;
1037 if (set->family == NFPROTO_IPV4) {
1038 h->dsize =
1039 sizeof(struct TOKEN(HTYPE, 4ct_elem));
1040 h->offset[IPSET_OFFSET_TIMEOUT] =
1041 offsetof(struct TOKEN(HTYPE, 4ct_elem),
1042 timeout);
1043 h->offset[IPSET_OFFSET_COUNTER] =
1044 offsetof(struct TOKEN(HTYPE, 4ct_elem),
1045 counter);
1046 TOKEN(HTYPE, 4_gc_init)(set,
1047 TOKEN(HTYPE, 4_gc));
1048 } else {
1049 h->dsize =
1050 sizeof(struct TOKEN(HTYPE, 6ct_elem));
1051 h->offset[IPSET_OFFSET_TIMEOUT] =
1052 offsetof(struct TOKEN(HTYPE, 6ct_elem),
1053 timeout);
1054 h->offset[IPSET_OFFSET_COUNTER] =
1055 offsetof(struct TOKEN(HTYPE, 6ct_elem),
1056 counter);
1057 TOKEN(HTYPE, 6_gc_init)(set,
1058 TOKEN(HTYPE, 6_gc));
1059 }
1060 } else {
1061 if (set->family == NFPROTO_IPV4) {
1062 h->dsize =
1063 sizeof(struct TOKEN(HTYPE, 4c_elem));
1064 h->offset[IPSET_OFFSET_COUNTER] =
1065 offsetof(struct TOKEN(HTYPE, 4c_elem),
1066 counter);
1067 } else {
1068 h->dsize =
1069 sizeof(struct TOKEN(HTYPE, 6c_elem));
1070 h->offset[IPSET_OFFSET_COUNTER] =
1071 offsetof(struct TOKEN(HTYPE, 6c_elem),
1072 counter);
1073 }
1074 }
1075 } else if (tb[IPSET_ATTR_TIMEOUT]) {
1076 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
1077 set->extensions |= IPSET_EXT_TIMEOUT;
1078 if (set->family == NFPROTO_IPV4) {
1079 h->dsize = sizeof(struct TOKEN(HTYPE, 4t_elem));
1080 h->offset[IPSET_OFFSET_TIMEOUT] =
1081 offsetof(struct TOKEN(HTYPE, 4t_elem),
1082 timeout);
1083 TOKEN(HTYPE, 4_gc_init)(set, TOKEN(HTYPE, 4_gc));
1084 } else {
1085 h->dsize = sizeof(struct TOKEN(HTYPE, 6t_elem));
1086 h->offset[IPSET_OFFSET_TIMEOUT] =
1087 offsetof(struct TOKEN(HTYPE, 6t_elem),
1088 timeout);
1089 TOKEN(HTYPE, 6_gc_init)(set, TOKEN(HTYPE, 6_gc));
1090 }
1091 } else { 1095 } else {
1096 set->variant = &IPSET_TOKEN(HTYPE, 6_variant);
1097 set->dsize = ip_set_elem_len(set, tb,
1098 sizeof(struct IPSET_TOKEN(HTYPE, 6_elem)));
1099 }
1100 if (tb[IPSET_ATTR_TIMEOUT]) {
1101 set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
1092 if (set->family == NFPROTO_IPV4) 1102 if (set->family == NFPROTO_IPV4)
1093 h->dsize = sizeof(struct TOKEN(HTYPE, 4_elem)); 1103 IPSET_TOKEN(HTYPE, 4_gc_init)(set,
1104 IPSET_TOKEN(HTYPE, 4_gc));
1094 else 1105 else
1095 h->dsize = sizeof(struct TOKEN(HTYPE, 6_elem)); 1106 IPSET_TOKEN(HTYPE, 6_gc_init)(set,
1107 IPSET_TOKEN(HTYPE, 6_gc));
1096 } 1108 }
1097 1109
1098 pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n", 1110 pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
1099 set->name, jhash_size(h->table->htable_bits), 1111 set->name, jhash_size(t->htable_bits),
1100 h->table->htable_bits, h->maxelem, set->data, h->table); 1112 t->htable_bits, h->maxelem, set->data, t);
1101 1113
1102 return 0; 1114 return 0;
1103} 1115}
diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
index c74e6e14cd93..e65fc2423d56 100644
--- a/net/netfilter/ipset/ip_set_hash_ip.c
+++ b/net/netfilter/ipset/ip_set_hash_ip.c
@@ -23,19 +23,20 @@
23#include <linux/netfilter/ipset/ip_set.h> 23#include <linux/netfilter/ipset/ip_set.h>
24#include <linux/netfilter/ipset/ip_set_hash.h> 24#include <linux/netfilter/ipset/ip_set_hash.h>
25 25
26#define REVISION_MIN 0 26#define IPSET_TYPE_REV_MIN 0
27#define REVISION_MAX 1 /* Counters support */ 27/* 1 Counters support */
28#define IPSET_TYPE_REV_MAX 2 /* Comments support */
28 29
29MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
30MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 31MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
31IP_SET_MODULE_DESC("hash:ip", REVISION_MIN, REVISION_MAX); 32IP_SET_MODULE_DESC("hash:ip", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
32MODULE_ALIAS("ip_set_hash:ip"); 33MODULE_ALIAS("ip_set_hash:ip");
33 34
34/* Type specific function prefix */ 35/* Type specific function prefix */
35#define HTYPE hash_ip 36#define HTYPE hash_ip
36#define IP_SET_HASH_WITH_NETMASK 37#define IP_SET_HASH_WITH_NETMASK
37 38
38/* IPv4 variants */ 39/* IPv4 variant */
39 40
40/* Member elements */ 41/* Member elements */
41struct hash_ip4_elem { 42struct hash_ip4_elem {
@@ -43,22 +44,6 @@ struct hash_ip4_elem {
43 __be32 ip; 44 __be32 ip;
44}; 45};
45 46
46struct hash_ip4t_elem {
47 __be32 ip;
48 unsigned long timeout;
49};
50
51struct hash_ip4c_elem {
52 __be32 ip;
53 struct ip_set_counter counter;
54};
55
56struct hash_ip4ct_elem {
57 __be32 ip;
58 struct ip_set_counter counter;
59 unsigned long timeout;
60};
61
62/* Common functions */ 47/* Common functions */
63 48
64static inline bool 49static inline bool
@@ -99,7 +84,7 @@ hash_ip4_kadt(struct ip_set *set, const struct sk_buff *skb,
99 const struct hash_ip *h = set->data; 84 const struct hash_ip *h = set->data;
100 ipset_adtfn adtfn = set->variant->adt[adt]; 85 ipset_adtfn adtfn = set->variant->adt[adt];
101 struct hash_ip4_elem e = {}; 86 struct hash_ip4_elem e = {};
102 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); 87 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
103 __be32 ip; 88 __be32 ip;
104 89
105 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip); 90 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip);
@@ -118,8 +103,8 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
118 const struct hash_ip *h = set->data; 103 const struct hash_ip *h = set->data;
119 ipset_adtfn adtfn = set->variant->adt[adt]; 104 ipset_adtfn adtfn = set->variant->adt[adt];
120 struct hash_ip4_elem e = {}; 105 struct hash_ip4_elem e = {};
121 struct ip_set_ext ext = IP_SET_INIT_UEXT(h); 106 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
122 u32 ip, ip_to, hosts; 107 u32 ip = 0, ip_to = 0, hosts;
123 int ret = 0; 108 int ret = 0;
124 109
125 if (unlikely(!tb[IPSET_ATTR_IP] || 110 if (unlikely(!tb[IPSET_ATTR_IP] ||
@@ -178,29 +163,13 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
178 return ret; 163 return ret;
179} 164}
180 165
181/* IPv6 variants */ 166/* IPv6 variant */
182 167
183/* Member elements */ 168/* Member elements */
184struct hash_ip6_elem { 169struct hash_ip6_elem {
185 union nf_inet_addr ip; 170 union nf_inet_addr ip;
186}; 171};
187 172
188struct hash_ip6t_elem {
189 union nf_inet_addr ip;
190 unsigned long timeout;
191};
192
193struct hash_ip6c_elem {
194 union nf_inet_addr ip;
195 struct ip_set_counter counter;
196};
197
198struct hash_ip6ct_elem {
199 union nf_inet_addr ip;
200 struct ip_set_counter counter;
201 unsigned long timeout;
202};
203
204/* Common functions */ 173/* Common functions */
205 174
206static inline bool 175static inline bool
@@ -253,7 +222,7 @@ hash_ip6_kadt(struct ip_set *set, const struct sk_buff *skb,
253 const struct hash_ip *h = set->data; 222 const struct hash_ip *h = set->data;
254 ipset_adtfn adtfn = set->variant->adt[adt]; 223 ipset_adtfn adtfn = set->variant->adt[adt];
255 struct hash_ip6_elem e = {}; 224 struct hash_ip6_elem e = {};
256 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); 225 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
257 226
258 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6); 227 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
259 hash_ip6_netmask(&e.ip, h->netmask); 228 hash_ip6_netmask(&e.ip, h->netmask);
@@ -270,7 +239,7 @@ hash_ip6_uadt(struct ip_set *set, struct nlattr *tb[],
270 const struct hash_ip *h = set->data; 239 const struct hash_ip *h = set->data;
271 ipset_adtfn adtfn = set->variant->adt[adt]; 240 ipset_adtfn adtfn = set->variant->adt[adt];
272 struct hash_ip6_elem e = {}; 241 struct hash_ip6_elem e = {};
273 struct ip_set_ext ext = IP_SET_INIT_UEXT(h); 242 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
274 int ret; 243 int ret;
275 244
276 if (unlikely(!tb[IPSET_ATTR_IP] || 245 if (unlikely(!tb[IPSET_ATTR_IP] ||
@@ -304,8 +273,8 @@ static struct ip_set_type hash_ip_type __read_mostly = {
304 .features = IPSET_TYPE_IP, 273 .features = IPSET_TYPE_IP,
305 .dimension = IPSET_DIM_ONE, 274 .dimension = IPSET_DIM_ONE,
306 .family = NFPROTO_UNSPEC, 275 .family = NFPROTO_UNSPEC,
307 .revision_min = REVISION_MIN, 276 .revision_min = IPSET_TYPE_REV_MIN,
308 .revision_max = REVISION_MAX, 277 .revision_max = IPSET_TYPE_REV_MAX,
309 .create = hash_ip_create, 278 .create = hash_ip_create,
310 .create_policy = { 279 .create_policy = {
311 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, 280 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
@@ -324,6 +293,7 @@ static struct ip_set_type hash_ip_type __read_mostly = {
324 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 293 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
325 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 294 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
326 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 295 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
296 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
327 }, 297 },
328 .me = THIS_MODULE, 298 .me = THIS_MODULE,
329}; 299};
diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
index 7a2d2bd98d04..525a595dd1fe 100644
--- a/net/netfilter/ipset/ip_set_hash_ipport.c
+++ b/net/netfilter/ipset/ip_set_hash_ipport.c
@@ -24,19 +24,20 @@
24#include <linux/netfilter/ipset/ip_set_getport.h> 24#include <linux/netfilter/ipset/ip_set_getport.h>
25#include <linux/netfilter/ipset/ip_set_hash.h> 25#include <linux/netfilter/ipset/ip_set_hash.h>
26 26
27#define REVISION_MIN 0 27#define IPSET_TYPE_REV_MIN 0
28/* 1 SCTP and UDPLITE support added */ 28/* 1 SCTP and UDPLITE support added */
29#define REVISION_MAX 2 /* Counters support added */ 29/* 2 Counters support added */
30#define IPSET_TYPE_REV_MAX 3 /* Comments support added */
30 31
31MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 33MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
33IP_SET_MODULE_DESC("hash:ip,port", REVISION_MIN, REVISION_MAX); 34IP_SET_MODULE_DESC("hash:ip,port", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
34MODULE_ALIAS("ip_set_hash:ip,port"); 35MODULE_ALIAS("ip_set_hash:ip,port");
35 36
36/* Type specific function prefix */ 37/* Type specific function prefix */
37#define HTYPE hash_ipport 38#define HTYPE hash_ipport
38 39
39/* IPv4 variants */ 40/* IPv4 variant */
40 41
41/* Member elements */ 42/* Member elements */
42struct hash_ipport4_elem { 43struct hash_ipport4_elem {
@@ -46,31 +47,6 @@ struct hash_ipport4_elem {
46 u8 padding; 47 u8 padding;
47}; 48};
48 49
49struct hash_ipport4t_elem {
50 __be32 ip;
51 __be16 port;
52 u8 proto;
53 u8 padding;
54 unsigned long timeout;
55};
56
57struct hash_ipport4c_elem {
58 __be32 ip;
59 __be16 port;
60 u8 proto;
61 u8 padding;
62 struct ip_set_counter counter;
63};
64
65struct hash_ipport4ct_elem {
66 __be32 ip;
67 __be16 port;
68 u8 proto;
69 u8 padding;
70 struct ip_set_counter counter;
71 unsigned long timeout;
72};
73
74/* Common functions */ 50/* Common functions */
75 51
76static inline bool 52static inline bool
@@ -116,10 +92,9 @@ hash_ipport4_kadt(struct ip_set *set, const struct sk_buff *skb,
116 const struct xt_action_param *par, 92 const struct xt_action_param *par,
117 enum ipset_adt adt, struct ip_set_adt_opt *opt) 93 enum ipset_adt adt, struct ip_set_adt_opt *opt)
118{ 94{
119 const struct hash_ipport *h = set->data;
120 ipset_adtfn adtfn = set->variant->adt[adt]; 95 ipset_adtfn adtfn = set->variant->adt[adt];
121 struct hash_ipport4_elem e = { }; 96 struct hash_ipport4_elem e = { };
122 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); 97 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
123 98
124 if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC, 99 if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
125 &e.port, &e.proto)) 100 &e.port, &e.proto))
@@ -136,8 +111,8 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
136 const struct hash_ipport *h = set->data; 111 const struct hash_ipport *h = set->data;
137 ipset_adtfn adtfn = set->variant->adt[adt]; 112 ipset_adtfn adtfn = set->variant->adt[adt];
138 struct hash_ipport4_elem e = { }; 113 struct hash_ipport4_elem e = { };
139 struct ip_set_ext ext = IP_SET_INIT_UEXT(h); 114 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
140 u32 ip, ip_to, p = 0, port, port_to; 115 u32 ip, ip_to = 0, p = 0, port, port_to;
141 bool with_ports = false; 116 bool with_ports = false;
142 int ret; 117 int ret;
143 118
@@ -222,7 +197,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
222 return ret; 197 return ret;
223} 198}
224 199
225/* IPv6 variants */ 200/* IPv6 variant */
226 201
227struct hash_ipport6_elem { 202struct hash_ipport6_elem {
228 union nf_inet_addr ip; 203 union nf_inet_addr ip;
@@ -231,31 +206,6 @@ struct hash_ipport6_elem {
231 u8 padding; 206 u8 padding;
232}; 207};
233 208
234struct hash_ipport6t_elem {
235 union nf_inet_addr ip;
236 __be16 port;
237 u8 proto;
238 u8 padding;
239 unsigned long timeout;
240};
241
242struct hash_ipport6c_elem {
243 union nf_inet_addr ip;
244 __be16 port;
245 u8 proto;
246 u8 padding;
247 struct ip_set_counter counter;
248};
249
250struct hash_ipport6ct_elem {
251 union nf_inet_addr ip;
252 __be16 port;
253 u8 proto;
254 u8 padding;
255 struct ip_set_counter counter;
256 unsigned long timeout;
257};
258
259/* Common functions */ 209/* Common functions */
260 210
261static inline bool 211static inline bool
@@ -306,10 +256,9 @@ hash_ipport6_kadt(struct ip_set *set, const struct sk_buff *skb,
306 const struct xt_action_param *par, 256 const struct xt_action_param *par,
307 enum ipset_adt adt, struct ip_set_adt_opt *opt) 257 enum ipset_adt adt, struct ip_set_adt_opt *opt)
308{ 258{
309 const struct hash_ipport *h = set->data;
310 ipset_adtfn adtfn = set->variant->adt[adt]; 259 ipset_adtfn adtfn = set->variant->adt[adt];
311 struct hash_ipport6_elem e = { }; 260 struct hash_ipport6_elem e = { };
312 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); 261 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
313 262
314 if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC, 263 if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
315 &e.port, &e.proto)) 264 &e.port, &e.proto))
@@ -326,7 +275,7 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
326 const struct hash_ipport *h = set->data; 275 const struct hash_ipport *h = set->data;
327 ipset_adtfn adtfn = set->variant->adt[adt]; 276 ipset_adtfn adtfn = set->variant->adt[adt];
328 struct hash_ipport6_elem e = { }; 277 struct hash_ipport6_elem e = { };
329 struct ip_set_ext ext = IP_SET_INIT_UEXT(h); 278 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
330 u32 port, port_to; 279 u32 port, port_to;
331 bool with_ports = false; 280 bool with_ports = false;
332 int ret; 281 int ret;
@@ -396,8 +345,8 @@ static struct ip_set_type hash_ipport_type __read_mostly = {
396 .features = IPSET_TYPE_IP | IPSET_TYPE_PORT, 345 .features = IPSET_TYPE_IP | IPSET_TYPE_PORT,
397 .dimension = IPSET_DIM_TWO, 346 .dimension = IPSET_DIM_TWO,
398 .family = NFPROTO_UNSPEC, 347 .family = NFPROTO_UNSPEC,
399 .revision_min = REVISION_MIN, 348 .revision_min = IPSET_TYPE_REV_MIN,
400 .revision_max = REVISION_MAX, 349 .revision_max = IPSET_TYPE_REV_MAX,
401 .create = hash_ipport_create, 350 .create = hash_ipport_create,
402 .create_policy = { 351 .create_policy = {
403 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, 352 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
@@ -419,6 +368,7 @@ static struct ip_set_type hash_ipport_type __read_mostly = {
419 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 368 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
420 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 369 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
421 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 370 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
371 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
422 }, 372 },
423 .me = THIS_MODULE, 373 .me = THIS_MODULE,
424}; 374};
diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
index 34e8a1acce42..f5636631466e 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportip.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
@@ -24,19 +24,20 @@
24#include <linux/netfilter/ipset/ip_set_getport.h> 24#include <linux/netfilter/ipset/ip_set_getport.h>
25#include <linux/netfilter/ipset/ip_set_hash.h> 25#include <linux/netfilter/ipset/ip_set_hash.h>
26 26
27#define REVISION_MIN 0 27#define IPSET_TYPE_REV_MIN 0
28/* 1 SCTP and UDPLITE support added */ 28/* 1 SCTP and UDPLITE support added */
29#define REVISION_MAX 2 /* Counters support added */ 29/* 2 Counters support added */
30#define IPSET_TYPE_REV_MAX 3 /* Comments support added */
30 31
31MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 33MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
33IP_SET_MODULE_DESC("hash:ip,port,ip", REVISION_MIN, REVISION_MAX); 34IP_SET_MODULE_DESC("hash:ip,port,ip", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
34MODULE_ALIAS("ip_set_hash:ip,port,ip"); 35MODULE_ALIAS("ip_set_hash:ip,port,ip");
35 36
36/* Type specific function prefix */ 37/* Type specific function prefix */
37#define HTYPE hash_ipportip 38#define HTYPE hash_ipportip
38 39
39/* IPv4 variants */ 40/* IPv4 variant */
40 41
41/* Member elements */ 42/* Member elements */
42struct hash_ipportip4_elem { 43struct hash_ipportip4_elem {
@@ -47,34 +48,6 @@ struct hash_ipportip4_elem {
47 u8 padding; 48 u8 padding;
48}; 49};
49 50
50struct hash_ipportip4t_elem {
51 __be32 ip;
52 __be32 ip2;
53 __be16 port;
54 u8 proto;
55 u8 padding;
56 unsigned long timeout;
57};
58
59struct hash_ipportip4c_elem {
60 __be32 ip;
61 __be32 ip2;
62 __be16 port;
63 u8 proto;
64 u8 padding;
65 struct ip_set_counter counter;
66};
67
68struct hash_ipportip4ct_elem {
69 __be32 ip;
70 __be32 ip2;
71 __be16 port;
72 u8 proto;
73 u8 padding;
74 struct ip_set_counter counter;
75 unsigned long timeout;
76};
77
78static inline bool 51static inline bool
79hash_ipportip4_data_equal(const struct hash_ipportip4_elem *ip1, 52hash_ipportip4_data_equal(const struct hash_ipportip4_elem *ip1,
80 const struct hash_ipportip4_elem *ip2, 53 const struct hash_ipportip4_elem *ip2,
@@ -120,10 +93,9 @@ hash_ipportip4_kadt(struct ip_set *set, const struct sk_buff *skb,
120 const struct xt_action_param *par, 93 const struct xt_action_param *par,
121 enum ipset_adt adt, struct ip_set_adt_opt *opt) 94 enum ipset_adt adt, struct ip_set_adt_opt *opt)
122{ 95{
123 const struct hash_ipportip *h = set->data;
124 ipset_adtfn adtfn = set->variant->adt[adt]; 96 ipset_adtfn adtfn = set->variant->adt[adt];
125 struct hash_ipportip4_elem e = { }; 97 struct hash_ipportip4_elem e = { };
126 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); 98 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
127 99
128 if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC, 100 if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
129 &e.port, &e.proto)) 101 &e.port, &e.proto))
@@ -141,8 +113,8 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
141 const struct hash_ipportip *h = set->data; 113 const struct hash_ipportip *h = set->data;
142 ipset_adtfn adtfn = set->variant->adt[adt]; 114 ipset_adtfn adtfn = set->variant->adt[adt];
143 struct hash_ipportip4_elem e = { }; 115 struct hash_ipportip4_elem e = { };
144 struct ip_set_ext ext = IP_SET_INIT_UEXT(h); 116 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
145 u32 ip, ip_to, p = 0, port, port_to; 117 u32 ip, ip_to = 0, p = 0, port, port_to;
146 bool with_ports = false; 118 bool with_ports = false;
147 int ret; 119 int ret;
148 120
@@ -231,7 +203,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
231 return ret; 203 return ret;
232} 204}
233 205
234/* IPv6 variants */ 206/* IPv6 variant */
235 207
236struct hash_ipportip6_elem { 208struct hash_ipportip6_elem {
237 union nf_inet_addr ip; 209 union nf_inet_addr ip;
@@ -241,34 +213,6 @@ struct hash_ipportip6_elem {
241 u8 padding; 213 u8 padding;
242}; 214};
243 215
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};
252
253struct hash_ipportip6c_elem {
254 union nf_inet_addr ip;
255 union nf_inet_addr ip2;
256 __be16 port;
257 u8 proto;
258 u8 padding;
259 struct ip_set_counter counter;
260};
261
262struct hash_ipportip6ct_elem {
263 union nf_inet_addr ip;
264 union nf_inet_addr ip2;
265 __be16 port;
266 u8 proto;
267 u8 padding;
268 struct ip_set_counter counter;
269 unsigned long timeout;
270};
271
272/* Common functions */ 216/* Common functions */
273 217
274static inline bool 218static inline bool
@@ -319,10 +263,9 @@ hash_ipportip6_kadt(struct ip_set *set, const struct sk_buff *skb,
319 const struct xt_action_param *par, 263 const struct xt_action_param *par,
320 enum ipset_adt adt, struct ip_set_adt_opt *opt) 264 enum ipset_adt adt, struct ip_set_adt_opt *opt)
321{ 265{
322 const struct hash_ipportip *h = set->data;
323 ipset_adtfn adtfn = set->variant->adt[adt]; 266 ipset_adtfn adtfn = set->variant->adt[adt];
324 struct hash_ipportip6_elem e = { }; 267 struct hash_ipportip6_elem e = { };
325 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); 268 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
326 269
327 if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC, 270 if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
328 &e.port, &e.proto)) 271 &e.port, &e.proto))
@@ -340,7 +283,7 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
340 const struct hash_ipportip *h = set->data; 283 const struct hash_ipportip *h = set->data;
341 ipset_adtfn adtfn = set->variant->adt[adt]; 284 ipset_adtfn adtfn = set->variant->adt[adt];
342 struct hash_ipportip6_elem e = { }; 285 struct hash_ipportip6_elem e = { };
343 struct ip_set_ext ext = IP_SET_INIT_UEXT(h); 286 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
344 u32 port, port_to; 287 u32 port, port_to;
345 bool with_ports = false; 288 bool with_ports = false;
346 int ret; 289 int ret;
@@ -414,8 +357,8 @@ static struct ip_set_type hash_ipportip_type __read_mostly = {
414 .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2, 357 .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2,
415 .dimension = IPSET_DIM_THREE, 358 .dimension = IPSET_DIM_THREE,
416 .family = NFPROTO_UNSPEC, 359 .family = NFPROTO_UNSPEC,
417 .revision_min = REVISION_MIN, 360 .revision_min = IPSET_TYPE_REV_MIN,
418 .revision_max = REVISION_MAX, 361 .revision_max = IPSET_TYPE_REV_MAX,
419 .create = hash_ipportip_create, 362 .create = hash_ipportip_create,
420 .create_policy = { 363 .create_policy = {
421 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, 364 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
@@ -437,6 +380,7 @@ static struct ip_set_type hash_ipportip_type __read_mostly = {
437 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 380 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
438 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 381 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
439 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 382 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
383 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
440 }, 384 },
441 .me = THIS_MODULE, 385 .me = THIS_MODULE,
442}; 386};
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
index f15f3e28b9c3..5d87fe8a41ff 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
@@ -24,15 +24,16 @@
24#include <linux/netfilter/ipset/ip_set_getport.h> 24#include <linux/netfilter/ipset/ip_set_getport.h>
25#include <linux/netfilter/ipset/ip_set_hash.h> 25#include <linux/netfilter/ipset/ip_set_hash.h>
26 26
27#define REVISION_MIN 0 27#define IPSET_TYPE_REV_MIN 0
28/* 1 SCTP and UDPLITE support added */ 28/* 1 SCTP and UDPLITE support added */
29/* 2 Range as input support for IPv4 added */ 29/* 2 Range as input support for IPv4 added */
30/* 3 nomatch flag support added */ 30/* 3 nomatch flag support added */
31#define REVISION_MAX 4 /* Counters support added */ 31/* 4 Counters support added */
32#define IPSET_TYPE_REV_MAX 5 /* Comments support added */
32 33
33MODULE_LICENSE("GPL"); 34MODULE_LICENSE("GPL");
34MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 35MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
35IP_SET_MODULE_DESC("hash:ip,port,net", REVISION_MIN, REVISION_MAX); 36IP_SET_MODULE_DESC("hash:ip,port,net", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
36MODULE_ALIAS("ip_set_hash:ip,port,net"); 37MODULE_ALIAS("ip_set_hash:ip,port,net");
37 38
38/* Type specific function prefix */ 39/* Type specific function prefix */
@@ -46,7 +47,7 @@ MODULE_ALIAS("ip_set_hash:ip,port,net");
46#define IP_SET_HASH_WITH_PROTO 47#define IP_SET_HASH_WITH_PROTO
47#define IP_SET_HASH_WITH_NETS 48#define IP_SET_HASH_WITH_NETS
48 49
49/* IPv4 variants */ 50/* IPv4 variant */
50 51
51/* Member elements */ 52/* Member elements */
52struct hash_ipportnet4_elem { 53struct hash_ipportnet4_elem {
@@ -58,37 +59,6 @@ struct hash_ipportnet4_elem {
58 u8 proto; 59 u8 proto;
59}; 60};
60 61
61struct hash_ipportnet4t_elem {
62 __be32 ip;
63 __be32 ip2;
64 __be16 port;
65 u8 cidr:7;
66 u8 nomatch:1;
67 u8 proto;
68 unsigned long timeout;
69};
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 */ 62/* Common functions */
93 63
94static inline bool 64static inline bool
@@ -170,9 +140,9 @@ hash_ipportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
170 const struct hash_ipportnet *h = set->data; 140 const struct hash_ipportnet *h = set->data;
171 ipset_adtfn adtfn = set->variant->adt[adt]; 141 ipset_adtfn adtfn = set->variant->adt[adt];
172 struct hash_ipportnet4_elem e = { 142 struct hash_ipportnet4_elem e = {
173 .cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1 143 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK) - 1,
174 }; 144 };
175 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); 145 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
176 146
177 if (adt == IPSET_TEST) 147 if (adt == IPSET_TEST)
178 e.cidr = HOST_MASK - 1; 148 e.cidr = HOST_MASK - 1;
@@ -195,9 +165,9 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
195 const struct hash_ipportnet *h = set->data; 165 const struct hash_ipportnet *h = set->data;
196 ipset_adtfn adtfn = set->variant->adt[adt]; 166 ipset_adtfn adtfn = set->variant->adt[adt];
197 struct hash_ipportnet4_elem e = { .cidr = HOST_MASK - 1 }; 167 struct hash_ipportnet4_elem e = { .cidr = HOST_MASK - 1 };
198 struct ip_set_ext ext = IP_SET_INIT_UEXT(h); 168 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
199 u32 ip, ip_to, p = 0, port, port_to; 169 u32 ip = 0, ip_to = 0, p = 0, port, port_to;
200 u32 ip2_from, ip2_to, ip2_last, ip2; 170 u32 ip2_from = 0, ip2_to = 0, ip2_last, ip2;
201 bool with_ports = false; 171 bool with_ports = false;
202 u8 cidr; 172 u8 cidr;
203 int ret; 173 int ret;
@@ -272,7 +242,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
272 if (ip > ip_to) 242 if (ip > ip_to)
273 swap(ip, ip_to); 243 swap(ip, ip_to);
274 } else if (tb[IPSET_ATTR_CIDR]) { 244 } else if (tb[IPSET_ATTR_CIDR]) {
275 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 245 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
276 246
277 if (!cidr || cidr > 32) 247 if (!cidr || cidr > 32)
278 return -IPSET_ERR_INVALID_CIDR; 248 return -IPSET_ERR_INVALID_CIDR;
@@ -306,9 +276,9 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
306 : port; 276 : port;
307 for (; p <= port_to; p++) { 277 for (; p <= port_to; p++) {
308 e.port = htons(p); 278 e.port = htons(p);
309 ip2 = retried 279 ip2 = retried &&
310 && ip == ntohl(h->next.ip) 280 ip == ntohl(h->next.ip) &&
311 && p == ntohs(h->next.port) 281 p == ntohs(h->next.port)
312 ? ntohl(h->next.ip2) : ip2_from; 282 ? ntohl(h->next.ip2) : ip2_from;
313 while (!after(ip2, ip2_to)) { 283 while (!after(ip2, ip2_to)) {
314 e.ip2 = htonl(ip2); 284 e.ip2 = htonl(ip2);
@@ -328,7 +298,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
328 return ret; 298 return ret;
329} 299}
330 300
331/* IPv6 variants */ 301/* IPv6 variant */
332 302
333struct hash_ipportnet6_elem { 303struct hash_ipportnet6_elem {
334 union nf_inet_addr ip; 304 union nf_inet_addr ip;
@@ -339,37 +309,6 @@ struct hash_ipportnet6_elem {
339 u8 proto; 309 u8 proto;
340}; 310};
341 311
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};
351
352struct hash_ipportnet6c_elem {
353 union nf_inet_addr ip;
354 union nf_inet_addr ip2;
355 __be16 port;
356 u8 cidr:7;
357 u8 nomatch:1;
358 u8 proto;
359 struct ip_set_counter counter;
360};
361
362struct hash_ipportnet6ct_elem {
363 union nf_inet_addr ip;
364 union nf_inet_addr ip2;
365 __be16 port;
366 u8 cidr:7;
367 u8 nomatch:1;
368 u8 proto;
369 struct ip_set_counter counter;
370 unsigned long timeout;
371};
372
373/* Common functions */ 312/* Common functions */
374 313
375static inline bool 314static inline bool
@@ -454,9 +393,9 @@ hash_ipportnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
454 const struct hash_ipportnet *h = set->data; 393 const struct hash_ipportnet *h = set->data;
455 ipset_adtfn adtfn = set->variant->adt[adt]; 394 ipset_adtfn adtfn = set->variant->adt[adt];
456 struct hash_ipportnet6_elem e = { 395 struct hash_ipportnet6_elem e = {
457 .cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1 396 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK) - 1,
458 }; 397 };
459 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); 398 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
460 399
461 if (adt == IPSET_TEST) 400 if (adt == IPSET_TEST)
462 e.cidr = HOST_MASK - 1; 401 e.cidr = HOST_MASK - 1;
@@ -479,7 +418,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
479 const struct hash_ipportnet *h = set->data; 418 const struct hash_ipportnet *h = set->data;
480 ipset_adtfn adtfn = set->variant->adt[adt]; 419 ipset_adtfn adtfn = set->variant->adt[adt];
481 struct hash_ipportnet6_elem e = { .cidr = HOST_MASK - 1 }; 420 struct hash_ipportnet6_elem e = { .cidr = HOST_MASK - 1 };
482 struct ip_set_ext ext = IP_SET_INIT_UEXT(h); 421 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
483 u32 port, port_to; 422 u32 port, port_to;
484 bool with_ports = false; 423 bool with_ports = false;
485 u8 cidr; 424 u8 cidr;
@@ -574,8 +513,8 @@ static struct ip_set_type hash_ipportnet_type __read_mostly = {
574 IPSET_TYPE_NOMATCH, 513 IPSET_TYPE_NOMATCH,
575 .dimension = IPSET_DIM_THREE, 514 .dimension = IPSET_DIM_THREE,
576 .family = NFPROTO_UNSPEC, 515 .family = NFPROTO_UNSPEC,
577 .revision_min = REVISION_MIN, 516 .revision_min = IPSET_TYPE_REV_MIN,
578 .revision_max = REVISION_MAX, 517 .revision_max = IPSET_TYPE_REV_MAX,
579 .create = hash_ipportnet_create, 518 .create = hash_ipportnet_create,
580 .create_policy = { 519 .create_policy = {
581 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, 520 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
@@ -600,6 +539,7 @@ static struct ip_set_type hash_ipportnet_type __read_mostly = {
600 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 539 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
601 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 540 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
602 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 541 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
542 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
603 }, 543 },
604 .me = THIS_MODULE, 544 .me = THIS_MODULE,
605}; 545};
diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c
index 223e9f546d0f..8295cf4f9fdc 100644
--- a/net/netfilter/ipset/ip_set_hash_net.c
+++ b/net/netfilter/ipset/ip_set_hash_net.c
@@ -22,21 +22,22 @@
22#include <linux/netfilter/ipset/ip_set.h> 22#include <linux/netfilter/ipset/ip_set.h>
23#include <linux/netfilter/ipset/ip_set_hash.h> 23#include <linux/netfilter/ipset/ip_set_hash.h>
24 24
25#define REVISION_MIN 0 25#define IPSET_TYPE_REV_MIN 0
26/* 1 Range as input support for IPv4 added */ 26/* 1 Range as input support for IPv4 added */
27/* 2 nomatch flag support added */ 27/* 2 nomatch flag support added */
28#define REVISION_MAX 3 /* Counters support added */ 28/* 3 Counters support added */
29#define IPSET_TYPE_REV_MAX 4 /* Comments support added */
29 30
30MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
31MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
32IP_SET_MODULE_DESC("hash:net", REVISION_MIN, REVISION_MAX); 33IP_SET_MODULE_DESC("hash:net", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
33MODULE_ALIAS("ip_set_hash:net"); 34MODULE_ALIAS("ip_set_hash:net");
34 35
35/* Type specific function prefix */ 36/* Type specific function prefix */
36#define HTYPE hash_net 37#define HTYPE hash_net
37#define IP_SET_HASH_WITH_NETS 38#define IP_SET_HASH_WITH_NETS
38 39
39/* IPv4 variants */ 40/* IPv4 variant */
40 41
41/* Member elements */ 42/* Member elements */
42struct hash_net4_elem { 43struct hash_net4_elem {
@@ -46,31 +47,6 @@ struct hash_net4_elem {
46 u8 cidr; 47 u8 cidr;
47}; 48};
48 49
49struct hash_net4t_elem {
50 __be32 ip;
51 u16 padding0;
52 u8 nomatch;
53 u8 cidr;
54 unsigned long timeout;
55};
56
57struct hash_net4c_elem {
58 __be32 ip;
59 u16 padding0;
60 u8 nomatch;
61 u8 cidr;
62 struct ip_set_counter counter;
63};
64
65struct hash_net4ct_elem {
66 __be32 ip;
67 u16 padding0;
68 u8 nomatch;
69 u8 cidr;
70 struct ip_set_counter counter;
71 unsigned long timeout;
72};
73
74/* Common functions */ 50/* Common functions */
75 51
76static inline bool 52static inline bool
@@ -143,9 +119,9 @@ hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb,
143 const struct hash_net *h = set->data; 119 const struct hash_net *h = set->data;
144 ipset_adtfn adtfn = set->variant->adt[adt]; 120 ipset_adtfn adtfn = set->variant->adt[adt];
145 struct hash_net4_elem e = { 121 struct hash_net4_elem e = {
146 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK 122 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK),
147 }; 123 };
148 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); 124 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
149 125
150 if (e.cidr == 0) 126 if (e.cidr == 0)
151 return -EINVAL; 127 return -EINVAL;
@@ -165,8 +141,8 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
165 const struct hash_net *h = set->data; 141 const struct hash_net *h = set->data;
166 ipset_adtfn adtfn = set->variant->adt[adt]; 142 ipset_adtfn adtfn = set->variant->adt[adt];
167 struct hash_net4_elem e = { .cidr = HOST_MASK }; 143 struct hash_net4_elem e = { .cidr = HOST_MASK };
168 struct ip_set_ext ext = IP_SET_INIT_UEXT(h); 144 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
169 u32 ip = 0, ip_to, last; 145 u32 ip = 0, ip_to = 0, last;
170 int ret; 146 int ret;
171 147
172 if (unlikely(!tb[IPSET_ATTR_IP] || 148 if (unlikely(!tb[IPSET_ATTR_IP] ||
@@ -228,7 +204,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
228 return ret; 204 return ret;
229} 205}
230 206
231/* IPv6 variants */ 207/* IPv6 variant */
232 208
233struct hash_net6_elem { 209struct hash_net6_elem {
234 union nf_inet_addr ip; 210 union nf_inet_addr ip;
@@ -237,31 +213,6 @@ struct hash_net6_elem {
237 u8 cidr; 213 u8 cidr;
238}; 214};
239 215
240struct hash_net6t_elem {
241 union nf_inet_addr ip;
242 u16 padding0;
243 u8 nomatch;
244 u8 cidr;
245 unsigned long timeout;
246};
247
248struct hash_net6c_elem {
249 union nf_inet_addr ip;
250 u16 padding0;
251 u8 nomatch;
252 u8 cidr;
253 struct ip_set_counter counter;
254};
255
256struct hash_net6ct_elem {
257 union nf_inet_addr ip;
258 u16 padding0;
259 u8 nomatch;
260 u8 cidr;
261 struct ip_set_counter counter;
262 unsigned long timeout;
263};
264
265/* Common functions */ 216/* Common functions */
266 217
267static inline bool 218static inline bool
@@ -338,9 +289,9 @@ hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb,
338 const struct hash_net *h = set->data; 289 const struct hash_net *h = set->data;
339 ipset_adtfn adtfn = set->variant->adt[adt]; 290 ipset_adtfn adtfn = set->variant->adt[adt];
340 struct hash_net6_elem e = { 291 struct hash_net6_elem e = {
341 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK 292 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK),
342 }; 293 };
343 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); 294 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
344 295
345 if (e.cidr == 0) 296 if (e.cidr == 0)
346 return -EINVAL; 297 return -EINVAL;
@@ -357,10 +308,9 @@ static int
357hash_net6_uadt(struct ip_set *set, struct nlattr *tb[], 308hash_net6_uadt(struct ip_set *set, struct nlattr *tb[],
358 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 309 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
359{ 310{
360 const struct hash_net *h = set->data;
361 ipset_adtfn adtfn = set->variant->adt[adt]; 311 ipset_adtfn adtfn = set->variant->adt[adt];
362 struct hash_net6_elem e = { .cidr = HOST_MASK }; 312 struct hash_net6_elem e = { .cidr = HOST_MASK };
363 struct ip_set_ext ext = IP_SET_INIT_UEXT(h); 313 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
364 int ret; 314 int ret;
365 315
366 if (unlikely(!tb[IPSET_ATTR_IP] || 316 if (unlikely(!tb[IPSET_ATTR_IP] ||
@@ -406,8 +356,8 @@ static struct ip_set_type hash_net_type __read_mostly = {
406 .features = IPSET_TYPE_IP | IPSET_TYPE_NOMATCH, 356 .features = IPSET_TYPE_IP | IPSET_TYPE_NOMATCH,
407 .dimension = IPSET_DIM_ONE, 357 .dimension = IPSET_DIM_ONE,
408 .family = NFPROTO_UNSPEC, 358 .family = NFPROTO_UNSPEC,
409 .revision_min = REVISION_MIN, 359 .revision_min = IPSET_TYPE_REV_MIN,
410 .revision_max = REVISION_MAX, 360 .revision_max = IPSET_TYPE_REV_MAX,
411 .create = hash_net_create, 361 .create = hash_net_create,
412 .create_policy = { 362 .create_policy = {
413 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, 363 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
@@ -425,6 +375,7 @@ static struct ip_set_type hash_net_type __read_mostly = {
425 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 375 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
426 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 376 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
427 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 377 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
378 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
428 }, 379 },
429 .me = THIS_MODULE, 380 .me = THIS_MODULE,
430}; 381};
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
index 7d798d5d5cd3..3f64a66bf5d9 100644
--- a/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -23,14 +23,15 @@
23#include <linux/netfilter/ipset/ip_set.h> 23#include <linux/netfilter/ipset/ip_set.h>
24#include <linux/netfilter/ipset/ip_set_hash.h> 24#include <linux/netfilter/ipset/ip_set_hash.h>
25 25
26#define REVISION_MIN 0 26#define IPSET_TYPE_REV_MIN 0
27/* 1 nomatch flag support added */ 27/* 1 nomatch flag support added */
28/* 2 /0 support added */ 28/* 2 /0 support added */
29#define REVISION_MAX 3 /* Counters support added */ 29/* 3 Counters support added */
30#define IPSET_TYPE_REV_MAX 4 /* Comments support added */
30 31
31MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 33MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
33IP_SET_MODULE_DESC("hash:net,iface", REVISION_MIN, REVISION_MAX); 34IP_SET_MODULE_DESC("hash:net,iface", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
34MODULE_ALIAS("ip_set_hash:net,iface"); 35MODULE_ALIAS("ip_set_hash:net,iface");
35 36
36/* Interface name rbtree */ 37/* Interface name rbtree */
@@ -134,7 +135,7 @@ iface_add(struct rb_root *root, const char **iface)
134 135
135#define STREQ(a, b) (strcmp(a, b) == 0) 136#define STREQ(a, b) (strcmp(a, b) == 0)
136 137
137/* IPv4 variants */ 138/* IPv4 variant */
138 139
139struct hash_netiface4_elem_hashed { 140struct hash_netiface4_elem_hashed {
140 __be32 ip; 141 __be32 ip;
@@ -144,7 +145,7 @@ struct hash_netiface4_elem_hashed {
144 u8 elem; 145 u8 elem;
145}; 146};
146 147
147/* Member elements without timeout */ 148/* Member elements */
148struct hash_netiface4_elem { 149struct hash_netiface4_elem {
149 __be32 ip; 150 __be32 ip;
150 u8 physdev; 151 u8 physdev;
@@ -154,37 +155,6 @@ struct hash_netiface4_elem {
154 const char *iface; 155 const char *iface;
155}; 156};
156 157
157struct hash_netiface4t_elem {
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 {
178 __be32 ip;
179 u8 physdev;
180 u8 cidr;
181 u8 nomatch;
182 u8 elem;
183 const char *iface;
184 struct ip_set_counter counter;
185 unsigned long timeout;
186};
187
188/* Common functions */ 158/* Common functions */
189 159
190static inline bool 160static inline bool
@@ -265,10 +235,10 @@ hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
265 struct hash_netiface *h = set->data; 235 struct hash_netiface *h = set->data;
266 ipset_adtfn adtfn = set->variant->adt[adt]; 236 ipset_adtfn adtfn = set->variant->adt[adt];
267 struct hash_netiface4_elem e = { 237 struct hash_netiface4_elem e = {
268 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK, 238 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK),
269 .elem = 1, 239 .elem = 1,
270 }; 240 };
271 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); 241 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
272 int ret; 242 int ret;
273 243
274 if (e.cidr == 0) 244 if (e.cidr == 0)
@@ -319,8 +289,8 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
319 struct hash_netiface *h = set->data; 289 struct hash_netiface *h = set->data;
320 ipset_adtfn adtfn = set->variant->adt[adt]; 290 ipset_adtfn adtfn = set->variant->adt[adt];
321 struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 }; 291 struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 };
322 struct ip_set_ext ext = IP_SET_INIT_UEXT(h); 292 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
323 u32 ip = 0, ip_to, last; 293 u32 ip = 0, ip_to = 0, last;
324 char iface[IFNAMSIZ]; 294 char iface[IFNAMSIZ];
325 int ret; 295 int ret;
326 296
@@ -399,7 +369,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
399 return ret; 369 return ret;
400} 370}
401 371
402/* IPv6 variants */ 372/* IPv6 variant */
403 373
404struct hash_netiface6_elem_hashed { 374struct hash_netiface6_elem_hashed {
405 union nf_inet_addr ip; 375 union nf_inet_addr ip;
@@ -418,37 +388,6 @@ struct hash_netiface6_elem {
418 const char *iface; 388 const char *iface;
419}; 389};
420 390
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 {
432 union nf_inet_addr ip;
433 u8 physdev;
434 u8 cidr;
435 u8 nomatch;
436 u8 elem;
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;
449 unsigned long timeout;
450};
451
452/* Common functions */ 391/* Common functions */
453 392
454static inline bool 393static inline bool
@@ -534,10 +473,10 @@ hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb,
534 struct hash_netiface *h = set->data; 473 struct hash_netiface *h = set->data;
535 ipset_adtfn adtfn = set->variant->adt[adt]; 474 ipset_adtfn adtfn = set->variant->adt[adt];
536 struct hash_netiface6_elem e = { 475 struct hash_netiface6_elem e = {
537 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK, 476 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK),
538 .elem = 1, 477 .elem = 1,
539 }; 478 };
540 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); 479 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
541 int ret; 480 int ret;
542 481
543 if (e.cidr == 0) 482 if (e.cidr == 0)
@@ -584,7 +523,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[],
584 struct hash_netiface *h = set->data; 523 struct hash_netiface *h = set->data;
585 ipset_adtfn adtfn = set->variant->adt[adt]; 524 ipset_adtfn adtfn = set->variant->adt[adt];
586 struct hash_netiface6_elem e = { .cidr = HOST_MASK, .elem = 1 }; 525 struct hash_netiface6_elem e = { .cidr = HOST_MASK, .elem = 1 };
587 struct ip_set_ext ext = IP_SET_INIT_UEXT(h); 526 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
588 char iface[IFNAMSIZ]; 527 char iface[IFNAMSIZ];
589 int ret; 528 int ret;
590 529
@@ -645,8 +584,8 @@ static struct ip_set_type hash_netiface_type __read_mostly = {
645 IPSET_TYPE_NOMATCH, 584 IPSET_TYPE_NOMATCH,
646 .dimension = IPSET_DIM_TWO, 585 .dimension = IPSET_DIM_TWO,
647 .family = NFPROTO_UNSPEC, 586 .family = NFPROTO_UNSPEC,
648 .revision_min = REVISION_MIN, 587 .revision_min = IPSET_TYPE_REV_MIN,
649 .revision_max = REVISION_MAX, 588 .revision_max = IPSET_TYPE_REV_MAX,
650 .create = hash_netiface_create, 589 .create = hash_netiface_create,
651 .create_policy = { 590 .create_policy = {
652 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, 591 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
@@ -668,6 +607,7 @@ static struct ip_set_type hash_netiface_type __read_mostly = {
668 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 607 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
669 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 608 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
670 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 609 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
610 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
671 }, 611 },
672 .me = THIS_MODULE, 612 .me = THIS_MODULE,
673}; 613};
diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c
new file mode 100644
index 000000000000..426032706ca9
--- /dev/null
+++ b/net/netfilter/ipset/ip_set_hash_netnet.c
@@ -0,0 +1,483 @@
1/* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
2 * Copyright (C) 2013 Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9/* Kernel module implementing an IP set type: the hash:net type */
10
11#include <linux/jhash.h>
12#include <linux/module.h>
13#include <linux/ip.h>
14#include <linux/skbuff.h>
15#include <linux/errno.h>
16#include <linux/random.h>
17#include <net/ip.h>
18#include <net/ipv6.h>
19#include <net/netlink.h>
20
21#include <linux/netfilter.h>
22#include <linux/netfilter/ipset/pfxlen.h>
23#include <linux/netfilter/ipset/ip_set.h>
24#include <linux/netfilter/ipset/ip_set_hash.h>
25
26#define IPSET_TYPE_REV_MIN 0
27#define IPSET_TYPE_REV_MAX 0
28
29MODULE_LICENSE("GPL");
30MODULE_AUTHOR("Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>");
31IP_SET_MODULE_DESC("hash:net,net", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
32MODULE_ALIAS("ip_set_hash:net,net");
33
34/* Type specific function prefix */
35#define HTYPE hash_netnet
36#define IP_SET_HASH_WITH_NETS
37#define IPSET_NET_COUNT 2
38
39/* IPv4 variants */
40
41/* Member elements */
42struct hash_netnet4_elem {
43 union {
44 __be32 ip[2];
45 __be64 ipcmp;
46 };
47 u8 nomatch;
48 union {
49 u8 cidr[2];
50 u16 ccmp;
51 };
52};
53
54/* Common functions */
55
56static inline bool
57hash_netnet4_data_equal(const struct hash_netnet4_elem *ip1,
58 const struct hash_netnet4_elem *ip2,
59 u32 *multi)
60{
61 return ip1->ipcmp == ip2->ipcmp &&
62 ip2->ccmp == ip2->ccmp;
63}
64
65static inline int
66hash_netnet4_do_data_match(const struct hash_netnet4_elem *elem)
67{
68 return elem->nomatch ? -ENOTEMPTY : 1;
69}
70
71static inline void
72hash_netnet4_data_set_flags(struct hash_netnet4_elem *elem, u32 flags)
73{
74 elem->nomatch = (flags >> 16) & IPSET_FLAG_NOMATCH;
75}
76
77static inline void
78hash_netnet4_data_reset_flags(struct hash_netnet4_elem *elem, u8 *flags)
79{
80 swap(*flags, elem->nomatch);
81}
82
83static inline void
84hash_netnet4_data_reset_elem(struct hash_netnet4_elem *elem,
85 struct hash_netnet4_elem *orig)
86{
87 elem->ip[1] = orig->ip[1];
88}
89
90static inline void
91hash_netnet4_data_netmask(struct hash_netnet4_elem *elem, u8 cidr, bool inner)
92{
93 if (inner) {
94 elem->ip[1] &= ip_set_netmask(cidr);
95 elem->cidr[1] = cidr;
96 } else {
97 elem->ip[0] &= ip_set_netmask(cidr);
98 elem->cidr[0] = cidr;
99 }
100}
101
102static bool
103hash_netnet4_data_list(struct sk_buff *skb,
104 const struct hash_netnet4_elem *data)
105{
106 u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
107
108 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip[0]) ||
109 nla_put_ipaddr4(skb, IPSET_ATTR_IP2, data->ip[1]) ||
110 nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr[0]) ||
111 nla_put_u8(skb, IPSET_ATTR_CIDR2, data->cidr[1]) ||
112 (flags &&
113 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
114 goto nla_put_failure;
115 return 0;
116
117nla_put_failure:
118 return 1;
119}
120
121static inline void
122hash_netnet4_data_next(struct hash_netnet4_elem *next,
123 const struct hash_netnet4_elem *d)
124{
125 next->ipcmp = d->ipcmp;
126}
127
128#define MTYPE hash_netnet4
129#define PF 4
130#define HOST_MASK 32
131#include "ip_set_hash_gen.h"
132
133static int
134hash_netnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
135 const struct xt_action_param *par,
136 enum ipset_adt adt, struct ip_set_adt_opt *opt)
137{
138 const struct hash_netnet *h = set->data;
139 ipset_adtfn adtfn = set->variant->adt[adt];
140 struct hash_netnet4_elem e = {
141 .cidr[0] = h->nets[0].cidr[0] ? h->nets[0].cidr[0] : HOST_MASK,
142 .cidr[1] = h->nets[0].cidr[1] ? h->nets[0].cidr[1] : HOST_MASK,
143 };
144 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
145
146 if (adt == IPSET_TEST)
147 e.ccmp = (HOST_MASK << (sizeof(e.cidr[0]) * 8)) | HOST_MASK;
148
149 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip[0]);
150 ip4addrptr(skb, opt->flags & IPSET_DIM_TWO_SRC, &e.ip[1]);
151 e.ip[0] &= ip_set_netmask(e.cidr[0]);
152 e.ip[1] &= ip_set_netmask(e.cidr[1]);
153
154 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
155}
156
157static int
158hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
159 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
160{
161 const struct hash_netnet *h = set->data;
162 ipset_adtfn adtfn = set->variant->adt[adt];
163 struct hash_netnet4_elem e = { .cidr[0] = HOST_MASK,
164 .cidr[1] = HOST_MASK };
165 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
166 u32 ip = 0, ip_to = 0, last;
167 u32 ip2 = 0, ip2_from = 0, ip2_to = 0, last2;
168 u8 cidr, cidr2;
169 int ret;
170
171 if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
172 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
173 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
174 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
175 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
176 return -IPSET_ERR_PROTOCOL;
177
178 if (tb[IPSET_ATTR_LINENO])
179 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
180
181 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip) ||
182 ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2], &ip2_from) ||
183 ip_set_get_extensions(set, tb, &ext);
184 if (ret)
185 return ret;
186
187 if (tb[IPSET_ATTR_CIDR]) {
188 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
189 if (!cidr || cidr > HOST_MASK)
190 return -IPSET_ERR_INVALID_CIDR;
191 e.cidr[0] = cidr;
192 }
193
194 if (tb[IPSET_ATTR_CIDR2]) {
195 cidr2 = nla_get_u8(tb[IPSET_ATTR_CIDR2]);
196 if (!cidr2 || cidr2 > HOST_MASK)
197 return -IPSET_ERR_INVALID_CIDR;
198 e.cidr[1] = cidr2;
199 }
200
201 if (tb[IPSET_ATTR_CADT_FLAGS]) {
202 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
203 if (cadt_flags & IPSET_FLAG_NOMATCH)
204 flags |= (IPSET_FLAG_NOMATCH << 16);
205 }
206
207 if (adt == IPSET_TEST || !(tb[IPSET_ATTR_IP_TO] &&
208 tb[IPSET_ATTR_IP2_TO])) {
209 e.ip[0] = htonl(ip & ip_set_hostmask(e.cidr[0]));
210 e.ip[1] = htonl(ip2_from & ip_set_hostmask(e.cidr[1]));
211 ret = adtfn(set, &e, &ext, &ext, flags);
212 return ip_set_enomatch(ret, flags, adt, set) ? -ret :
213 ip_set_eexist(ret, flags) ? 0 : ret;
214 }
215
216 ip_to = ip;
217 if (tb[IPSET_ATTR_IP_TO]) {
218 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
219 if (ret)
220 return ret;
221 if (ip_to < ip)
222 swap(ip, ip_to);
223 if (ip + UINT_MAX == ip_to)
224 return -IPSET_ERR_HASH_RANGE;
225 }
226
227 ip2_to = ip2_from;
228 if (tb[IPSET_ATTR_IP2_TO]) {
229 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to);
230 if (ret)
231 return ret;
232 if (ip2_to < ip2_from)
233 swap(ip2_from, ip2_to);
234 if (ip2_from + UINT_MAX == ip2_to)
235 return -IPSET_ERR_HASH_RANGE;
236
237 }
238
239 if (retried)
240 ip = ntohl(h->next.ip[0]);
241
242 while (!after(ip, ip_to)) {
243 e.ip[0] = htonl(ip);
244 last = ip_set_range_to_cidr(ip, ip_to, &cidr);
245 e.cidr[0] = cidr;
246 ip2 = (retried &&
247 ip == ntohl(h->next.ip[0])) ? ntohl(h->next.ip[1])
248 : ip2_from;
249 while (!after(ip2, ip2_to)) {
250 e.ip[1] = htonl(ip2);
251 last2 = ip_set_range_to_cidr(ip2, ip2_to, &cidr2);
252 e.cidr[1] = cidr2;
253 ret = adtfn(set, &e, &ext, &ext, flags);
254 if (ret && !ip_set_eexist(ret, flags))
255 return ret;
256 else
257 ret = 0;
258 ip2 = last2 + 1;
259 }
260 ip = last + 1;
261 }
262 return ret;
263}
264
265/* IPv6 variants */
266
267struct hash_netnet6_elem {
268 union nf_inet_addr ip[2];
269 u8 nomatch;
270 union {
271 u8 cidr[2];
272 u16 ccmp;
273 };
274};
275
276/* Common functions */
277
278static inline bool
279hash_netnet6_data_equal(const struct hash_netnet6_elem *ip1,
280 const struct hash_netnet6_elem *ip2,
281 u32 *multi)
282{
283 return ipv6_addr_equal(&ip1->ip[0].in6, &ip2->ip[0].in6) &&
284 ipv6_addr_equal(&ip1->ip[1].in6, &ip2->ip[1].in6) &&
285 ip1->ccmp == ip2->ccmp;
286}
287
288static inline int
289hash_netnet6_do_data_match(const struct hash_netnet6_elem *elem)
290{
291 return elem->nomatch ? -ENOTEMPTY : 1;
292}
293
294static inline void
295hash_netnet6_data_set_flags(struct hash_netnet6_elem *elem, u32 flags)
296{
297 elem->nomatch = (flags >> 16) & IPSET_FLAG_NOMATCH;
298}
299
300static inline void
301hash_netnet6_data_reset_flags(struct hash_netnet6_elem *elem, u8 *flags)
302{
303 swap(*flags, elem->nomatch);
304}
305
306static inline void
307hash_netnet6_data_reset_elem(struct hash_netnet6_elem *elem,
308 struct hash_netnet6_elem *orig)
309{
310 elem->ip[1] = orig->ip[1];
311}
312
313static inline void
314hash_netnet6_data_netmask(struct hash_netnet6_elem *elem, u8 cidr, bool inner)
315{
316 if (inner) {
317 ip6_netmask(&elem->ip[1], cidr);
318 elem->cidr[1] = cidr;
319 } else {
320 ip6_netmask(&elem->ip[0], cidr);
321 elem->cidr[0] = cidr;
322 }
323}
324
325static bool
326hash_netnet6_data_list(struct sk_buff *skb,
327 const struct hash_netnet6_elem *data)
328{
329 u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
330
331 if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip[0].in6) ||
332 nla_put_ipaddr6(skb, IPSET_ATTR_IP2, &data->ip[1].in6) ||
333 nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr[0]) ||
334 nla_put_u8(skb, IPSET_ATTR_CIDR2, data->cidr[1]) ||
335 (flags &&
336 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
337 goto nla_put_failure;
338 return 0;
339
340nla_put_failure:
341 return 1;
342}
343
344static inline void
345hash_netnet6_data_next(struct hash_netnet4_elem *next,
346 const struct hash_netnet6_elem *d)
347{
348}
349
350#undef MTYPE
351#undef PF
352#undef HOST_MASK
353
354#define MTYPE hash_netnet6
355#define PF 6
356#define HOST_MASK 128
357#define IP_SET_EMIT_CREATE
358#include "ip_set_hash_gen.h"
359
360static int
361hash_netnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
362 const struct xt_action_param *par,
363 enum ipset_adt adt, struct ip_set_adt_opt *opt)
364{
365 const struct hash_netnet *h = set->data;
366 ipset_adtfn adtfn = set->variant->adt[adt];
367 struct hash_netnet6_elem e = {
368 .cidr[0] = h->nets[0].cidr[0] ? h->nets[0].cidr[0] : HOST_MASK,
369 .cidr[1] = h->nets[0].cidr[1] ? h->nets[0].cidr[1] : HOST_MASK
370 };
371 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
372
373 if (adt == IPSET_TEST)
374 e.ccmp = (HOST_MASK << (sizeof(u8)*8)) | HOST_MASK;
375
376 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip[0].in6);
377 ip6addrptr(skb, opt->flags & IPSET_DIM_TWO_SRC, &e.ip[1].in6);
378 ip6_netmask(&e.ip[0], e.cidr[0]);
379 ip6_netmask(&e.ip[1], e.cidr[1]);
380
381 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
382}
383
384static int
385hash_netnet6_uadt(struct ip_set *set, struct nlattr *tb[],
386 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
387{
388 ipset_adtfn adtfn = set->variant->adt[adt];
389 struct hash_netnet6_elem e = { .cidr[0] = HOST_MASK,
390 .cidr[1] = HOST_MASK };
391 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
392 int ret;
393
394 if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
395 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
396 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
397 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
398 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
399 return -IPSET_ERR_PROTOCOL;
400 if (unlikely(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_IP2_TO]))
401 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED;
402
403 if (tb[IPSET_ATTR_LINENO])
404 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
405
406 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip[0]) ||
407 ip_set_get_ipaddr6(tb[IPSET_ATTR_IP2], &e.ip[1]) ||
408 ip_set_get_extensions(set, tb, &ext);
409 if (ret)
410 return ret;
411
412 if (tb[IPSET_ATTR_CIDR])
413 e.cidr[0] = nla_get_u8(tb[IPSET_ATTR_CIDR]);
414
415 if (tb[IPSET_ATTR_CIDR2])
416 e.cidr[1] = nla_get_u8(tb[IPSET_ATTR_CIDR2]);
417
418 if (!e.cidr[0] || e.cidr[0] > HOST_MASK || !e.cidr[1] ||
419 e.cidr[1] > HOST_MASK)
420 return -IPSET_ERR_INVALID_CIDR;
421
422 ip6_netmask(&e.ip[0], e.cidr[0]);
423 ip6_netmask(&e.ip[1], e.cidr[1]);
424
425 if (tb[IPSET_ATTR_CADT_FLAGS]) {
426 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
427 if (cadt_flags & IPSET_FLAG_NOMATCH)
428 flags |= (IPSET_FLAG_NOMATCH << 16);
429 }
430
431 ret = adtfn(set, &e, &ext, &ext, flags);
432
433 return ip_set_enomatch(ret, flags, adt, set) ? -ret :
434 ip_set_eexist(ret, flags) ? 0 : ret;
435}
436
437static struct ip_set_type hash_netnet_type __read_mostly = {
438 .name = "hash:net,net",
439 .protocol = IPSET_PROTOCOL,
440 .features = IPSET_TYPE_IP | IPSET_TYPE_IP2 | IPSET_TYPE_NOMATCH,
441 .dimension = IPSET_DIM_TWO,
442 .family = NFPROTO_UNSPEC,
443 .revision_min = IPSET_TYPE_REV_MIN,
444 .revision_max = IPSET_TYPE_REV_MAX,
445 .create = hash_netnet_create,
446 .create_policy = {
447 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
448 [IPSET_ATTR_MAXELEM] = { .type = NLA_U32 },
449 [IPSET_ATTR_PROBES] = { .type = NLA_U8 },
450 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 },
451 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
452 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
453 },
454 .adt_policy = {
455 [IPSET_ATTR_IP] = { .type = NLA_NESTED },
456 [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED },
457 [IPSET_ATTR_IP2] = { .type = NLA_NESTED },
458 [IPSET_ATTR_IP2_TO] = { .type = NLA_NESTED },
459 [IPSET_ATTR_CIDR] = { .type = NLA_U8 },
460 [IPSET_ATTR_CIDR2] = { .type = NLA_U8 },
461 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
462 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
463 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
464 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
465 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
466 },
467 .me = THIS_MODULE,
468};
469
470static int __init
471hash_netnet_init(void)
472{
473 return ip_set_type_register(&hash_netnet_type);
474}
475
476static void __exit
477hash_netnet_fini(void)
478{
479 ip_set_type_unregister(&hash_netnet_type);
480}
481
482module_init(hash_netnet_init);
483module_exit(hash_netnet_fini);
diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c
index 09d6690bee6f..7097fb0141bf 100644
--- a/net/netfilter/ipset/ip_set_hash_netport.c
+++ b/net/netfilter/ipset/ip_set_hash_netport.c
@@ -23,15 +23,16 @@
23#include <linux/netfilter/ipset/ip_set_getport.h> 23#include <linux/netfilter/ipset/ip_set_getport.h>
24#include <linux/netfilter/ipset/ip_set_hash.h> 24#include <linux/netfilter/ipset/ip_set_hash.h>
25 25
26#define REVISION_MIN 0 26#define IPSET_TYPE_REV_MIN 0
27/* 1 SCTP and UDPLITE support added */ 27/* 1 SCTP and UDPLITE support added */
28/* 2 Range as input support for IPv4 added */ 28/* 2 Range as input support for IPv4 added */
29/* 3 nomatch flag support added */ 29/* 3 nomatch flag support added */
30#define REVISION_MAX 4 /* Counters support added */ 30/* 4 Counters support added */
31#define IPSET_TYPE_REV_MAX 5 /* Comments support added */
31 32
32MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
33MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 34MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
34IP_SET_MODULE_DESC("hash:net,port", REVISION_MIN, REVISION_MAX); 35IP_SET_MODULE_DESC("hash:net,port", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
35MODULE_ALIAS("ip_set_hash:net,port"); 36MODULE_ALIAS("ip_set_hash:net,port");
36 37
37/* Type specific function prefix */ 38/* Type specific function prefix */
@@ -45,7 +46,7 @@ MODULE_ALIAS("ip_set_hash:net,port");
45 */ 46 */
46#define IP_SET_HASH_WITH_NETS_PACKED 47#define IP_SET_HASH_WITH_NETS_PACKED
47 48
48/* IPv4 variants */ 49/* IPv4 variant */
49 50
50/* Member elements */ 51/* Member elements */
51struct hash_netport4_elem { 52struct hash_netport4_elem {
@@ -56,34 +57,6 @@ struct hash_netport4_elem {
56 u8 nomatch:1; 57 u8 nomatch:1;
57}; 58};
58 59
59struct hash_netport4t_elem {
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 {
78 __be32 ip;
79 __be16 port;
80 u8 proto;
81 u8 cidr:7;
82 u8 nomatch:1;
83 struct ip_set_counter counter;
84 unsigned long timeout;
85};
86
87/* Common functions */ 60/* Common functions */
88 61
89static inline bool 62static inline bool
@@ -162,9 +135,9 @@ hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb,
162 const struct hash_netport *h = set->data; 135 const struct hash_netport *h = set->data;
163 ipset_adtfn adtfn = set->variant->adt[adt]; 136 ipset_adtfn adtfn = set->variant->adt[adt];
164 struct hash_netport4_elem e = { 137 struct hash_netport4_elem e = {
165 .cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1 138 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK) - 1,
166 }; 139 };
167 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); 140 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
168 141
169 if (adt == IPSET_TEST) 142 if (adt == IPSET_TEST)
170 e.cidr = HOST_MASK - 1; 143 e.cidr = HOST_MASK - 1;
@@ -186,8 +159,8 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
186 const struct hash_netport *h = set->data; 159 const struct hash_netport *h = set->data;
187 ipset_adtfn adtfn = set->variant->adt[adt]; 160 ipset_adtfn adtfn = set->variant->adt[adt];
188 struct hash_netport4_elem e = { .cidr = HOST_MASK - 1 }; 161 struct hash_netport4_elem e = { .cidr = HOST_MASK - 1 };
189 struct ip_set_ext ext = IP_SET_INIT_UEXT(h); 162 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
190 u32 port, port_to, p = 0, ip = 0, ip_to, last; 163 u32 port, port_to, p = 0, ip = 0, ip_to = 0, last;
191 bool with_ports = false; 164 bool with_ports = false;
192 u8 cidr; 165 u8 cidr;
193 int ret; 166 int ret;
@@ -287,7 +260,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
287 return ret; 260 return ret;
288} 261}
289 262
290/* IPv6 variants */ 263/* IPv6 variant */
291 264
292struct hash_netport6_elem { 265struct hash_netport6_elem {
293 union nf_inet_addr ip; 266 union nf_inet_addr ip;
@@ -297,34 +270,6 @@ struct hash_netport6_elem {
297 u8 nomatch:1; 270 u8 nomatch:1;
298}; 271};
299 272
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};
308
309struct hash_netport6c_elem {
310 union nf_inet_addr ip;
311 __be16 port;
312 u8 proto;
313 u8 cidr:7;
314 u8 nomatch:1;
315 struct ip_set_counter counter;
316};
317
318struct hash_netport6ct_elem {
319 union nf_inet_addr ip;
320 __be16 port;
321 u8 proto;
322 u8 cidr:7;
323 u8 nomatch:1;
324 struct ip_set_counter counter;
325 unsigned long timeout;
326};
327
328/* Common functions */ 273/* Common functions */
329 274
330static inline bool 275static inline bool
@@ -407,9 +352,9 @@ hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb,
407 const struct hash_netport *h = set->data; 352 const struct hash_netport *h = set->data;
408 ipset_adtfn adtfn = set->variant->adt[adt]; 353 ipset_adtfn adtfn = set->variant->adt[adt];
409 struct hash_netport6_elem e = { 354 struct hash_netport6_elem e = {
410 .cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1, 355 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK) - 1,
411 }; 356 };
412 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); 357 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
413 358
414 if (adt == IPSET_TEST) 359 if (adt == IPSET_TEST)
415 e.cidr = HOST_MASK - 1; 360 e.cidr = HOST_MASK - 1;
@@ -431,7 +376,7 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
431 const struct hash_netport *h = set->data; 376 const struct hash_netport *h = set->data;
432 ipset_adtfn adtfn = set->variant->adt[adt]; 377 ipset_adtfn adtfn = set->variant->adt[adt];
433 struct hash_netport6_elem e = { .cidr = HOST_MASK - 1 }; 378 struct hash_netport6_elem e = { .cidr = HOST_MASK - 1 };
434 struct ip_set_ext ext = IP_SET_INIT_UEXT(h); 379 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
435 u32 port, port_to; 380 u32 port, port_to;
436 bool with_ports = false; 381 bool with_ports = false;
437 u8 cidr; 382 u8 cidr;
@@ -518,8 +463,8 @@ static struct ip_set_type hash_netport_type __read_mostly = {
518 .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_NOMATCH, 463 .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_NOMATCH,
519 .dimension = IPSET_DIM_TWO, 464 .dimension = IPSET_DIM_TWO,
520 .family = NFPROTO_UNSPEC, 465 .family = NFPROTO_UNSPEC,
521 .revision_min = REVISION_MIN, 466 .revision_min = IPSET_TYPE_REV_MIN,
522 .revision_max = REVISION_MAX, 467 .revision_max = IPSET_TYPE_REV_MAX,
523 .create = hash_netport_create, 468 .create = hash_netport_create,
524 .create_policy = { 469 .create_policy = {
525 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, 470 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
@@ -542,6 +487,7 @@ static struct ip_set_type hash_netport_type __read_mostly = {
542 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 487 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
543 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 488 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
544 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 489 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
490 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
545 }, 491 },
546 .me = THIS_MODULE, 492 .me = THIS_MODULE,
547}; 493};
diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c
new file mode 100644
index 000000000000..363fab933d48
--- /dev/null
+++ b/net/netfilter/ipset/ip_set_hash_netportnet.c
@@ -0,0 +1,588 @@
1/* Copyright (C) 2003-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/* Kernel module implementing an IP set type: the hash:ip,port,net type */
9
10#include <linux/jhash.h>
11#include <linux/module.h>
12#include <linux/ip.h>
13#include <linux/skbuff.h>
14#include <linux/errno.h>
15#include <linux/random.h>
16#include <net/ip.h>
17#include <net/ipv6.h>
18#include <net/netlink.h>
19#include <net/tcp.h>
20
21#include <linux/netfilter.h>
22#include <linux/netfilter/ipset/pfxlen.h>
23#include <linux/netfilter/ipset/ip_set.h>
24#include <linux/netfilter/ipset/ip_set_getport.h>
25#include <linux/netfilter/ipset/ip_set_hash.h>
26
27#define IPSET_TYPE_REV_MIN 0
28#define IPSET_TYPE_REV_MAX 0 /* Comments support added */
29
30MODULE_LICENSE("GPL");
31MODULE_AUTHOR("Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>");
32IP_SET_MODULE_DESC("hash:net,port,net", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
33MODULE_ALIAS("ip_set_hash:net,port,net");
34
35/* Type specific function prefix */
36#define HTYPE hash_netportnet
37#define IP_SET_HASH_WITH_PROTO
38#define IP_SET_HASH_WITH_NETS
39#define IPSET_NET_COUNT 2
40
41/* IPv4 variant */
42
43/* Member elements */
44struct hash_netportnet4_elem {
45 union {
46 __be32 ip[2];
47 __be64 ipcmp;
48 };
49 __be16 port;
50 union {
51 u8 cidr[2];
52 u16 ccmp;
53 };
54 u8 nomatch:1;
55 u8 proto;
56};
57
58/* Common functions */
59
60static inline bool
61hash_netportnet4_data_equal(const struct hash_netportnet4_elem *ip1,
62 const struct hash_netportnet4_elem *ip2,
63 u32 *multi)
64{
65 return ip1->ipcmp == ip2->ipcmp &&
66 ip1->ccmp == ip2->ccmp &&
67 ip1->port == ip2->port &&
68 ip1->proto == ip2->proto;
69}
70
71static inline int
72hash_netportnet4_do_data_match(const struct hash_netportnet4_elem *elem)
73{
74 return elem->nomatch ? -ENOTEMPTY : 1;
75}
76
77static inline void
78hash_netportnet4_data_set_flags(struct hash_netportnet4_elem *elem, u32 flags)
79{
80 elem->nomatch = !!((flags >> 16) & IPSET_FLAG_NOMATCH);
81}
82
83static inline void
84hash_netportnet4_data_reset_flags(struct hash_netportnet4_elem *elem, u8 *flags)
85{
86 swap(*flags, elem->nomatch);
87}
88
89static inline void
90hash_netportnet4_data_reset_elem(struct hash_netportnet4_elem *elem,
91 struct hash_netportnet4_elem *orig)
92{
93 elem->ip[1] = orig->ip[1];
94}
95
96static inline void
97hash_netportnet4_data_netmask(struct hash_netportnet4_elem *elem,
98 u8 cidr, bool inner)
99{
100 if (inner) {
101 elem->ip[1] &= ip_set_netmask(cidr);
102 elem->cidr[1] = cidr;
103 } else {
104 elem->ip[0] &= ip_set_netmask(cidr);
105 elem->cidr[0] = cidr;
106 }
107}
108
109static bool
110hash_netportnet4_data_list(struct sk_buff *skb,
111 const struct hash_netportnet4_elem *data)
112{
113 u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
114
115 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip[0]) ||
116 nla_put_ipaddr4(skb, IPSET_ATTR_IP2, data->ip[1]) ||
117 nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
118 nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr[0]) ||
119 nla_put_u8(skb, IPSET_ATTR_CIDR2, data->cidr[1]) ||
120 nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
121 (flags &&
122 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
123 goto nla_put_failure;
124 return 0;
125
126nla_put_failure:
127 return 1;
128}
129
130static inline void
131hash_netportnet4_data_next(struct hash_netportnet4_elem *next,
132 const struct hash_netportnet4_elem *d)
133{
134 next->ipcmp = d->ipcmp;
135 next->port = d->port;
136}
137
138#define MTYPE hash_netportnet4
139#define PF 4
140#define HOST_MASK 32
141#include "ip_set_hash_gen.h"
142
143static int
144hash_netportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
145 const struct xt_action_param *par,
146 enum ipset_adt adt, struct ip_set_adt_opt *opt)
147{
148 const struct hash_netportnet *h = set->data;
149 ipset_adtfn adtfn = set->variant->adt[adt];
150 struct hash_netportnet4_elem e = {
151 .cidr[0] = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK),
152 .cidr[1] = IP_SET_INIT_CIDR(h->nets[0].cidr[1], HOST_MASK),
153 };
154 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
155
156 if (adt == IPSET_TEST)
157 e.ccmp = (HOST_MASK << (sizeof(e.cidr[0]) * 8)) | HOST_MASK;
158
159 if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
160 &e.port, &e.proto))
161 return -EINVAL;
162
163 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip[0]);
164 ip4addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &e.ip[1]);
165 e.ip[0] &= ip_set_netmask(e.cidr[0]);
166 e.ip[1] &= ip_set_netmask(e.cidr[1]);
167
168 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
169}
170
171static int
172hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
173 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
174{
175 const struct hash_netportnet *h = set->data;
176 ipset_adtfn adtfn = set->variant->adt[adt];
177 struct hash_netportnet4_elem e = { .cidr[0] = HOST_MASK,
178 .cidr[1] = HOST_MASK };
179 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
180 u32 ip = 0, ip_to = 0, ip_last, p = 0, port, port_to;
181 u32 ip2_from = 0, ip2_to = 0, ip2_last, ip2;
182 bool with_ports = false;
183 u8 cidr, cidr2;
184 int ret;
185
186 if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
187 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
188 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
189 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
190 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
191 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
192 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
193 return -IPSET_ERR_PROTOCOL;
194
195 if (tb[IPSET_ATTR_LINENO])
196 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
197
198 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip) ||
199 ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2], &ip2_from) ||
200 ip_set_get_extensions(set, tb, &ext);
201 if (ret)
202 return ret;
203
204 if (tb[IPSET_ATTR_CIDR]) {
205 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
206 if (!cidr || cidr > HOST_MASK)
207 return -IPSET_ERR_INVALID_CIDR;
208 e.cidr[0] = cidr;
209 }
210
211 if (tb[IPSET_ATTR_CIDR2]) {
212 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR2]);
213 if (!cidr || cidr > HOST_MASK)
214 return -IPSET_ERR_INVALID_CIDR;
215 e.cidr[1] = cidr;
216 }
217
218 if (tb[IPSET_ATTR_PORT])
219 e.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
220 else
221 return -IPSET_ERR_PROTOCOL;
222
223 if (tb[IPSET_ATTR_PROTO]) {
224 e.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
225 with_ports = ip_set_proto_with_ports(e.proto);
226
227 if (e.proto == 0)
228 return -IPSET_ERR_INVALID_PROTO;
229 } else
230 return -IPSET_ERR_MISSING_PROTO;
231
232 if (!(with_ports || e.proto == IPPROTO_ICMP))
233 e.port = 0;
234
235 if (tb[IPSET_ATTR_CADT_FLAGS]) {
236 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
237 if (cadt_flags & IPSET_FLAG_NOMATCH)
238 flags |= (IPSET_FLAG_NOMATCH << 16);
239 }
240
241 with_ports = with_ports && tb[IPSET_ATTR_PORT_TO];
242 if (adt == IPSET_TEST ||
243 !(tb[IPSET_ATTR_IP_TO] || with_ports || tb[IPSET_ATTR_IP2_TO])) {
244 e.ip[0] = htonl(ip & ip_set_hostmask(e.cidr[0]));
245 e.ip[1] = htonl(ip2_from & ip_set_hostmask(e.cidr[1]));
246 ret = adtfn(set, &e, &ext, &ext, flags);
247 return ip_set_enomatch(ret, flags, adt, set) ? -ret :
248 ip_set_eexist(ret, flags) ? 0 : ret;
249 }
250
251 ip_to = ip;
252 if (tb[IPSET_ATTR_IP_TO]) {
253 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
254 if (ret)
255 return ret;
256 if (ip > ip_to)
257 swap(ip, ip_to);
258 if (unlikely(ip + UINT_MAX == ip_to))
259 return -IPSET_ERR_HASH_RANGE;
260 }
261
262 port_to = port = ntohs(e.port);
263 if (tb[IPSET_ATTR_PORT_TO]) {
264 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
265 if (port > port_to)
266 swap(port, port_to);
267 }
268
269 ip2_to = ip2_from;
270 if (tb[IPSET_ATTR_IP2_TO]) {
271 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to);
272 if (ret)
273 return ret;
274 if (ip2_from > ip2_to)
275 swap(ip2_from, ip2_to);
276 if (unlikely(ip2_from + UINT_MAX == ip2_to))
277 return -IPSET_ERR_HASH_RANGE;
278 }
279
280 if (retried)
281 ip = ntohl(h->next.ip[0]);
282
283 while (!after(ip, ip_to)) {
284 e.ip[0] = htonl(ip);
285 ip_last = ip_set_range_to_cidr(ip, ip_to, &cidr);
286 e.cidr[0] = cidr;
287 p = retried && ip == ntohl(h->next.ip[0]) ? ntohs(h->next.port)
288 : port;
289 for (; p <= port_to; p++) {
290 e.port = htons(p);
291 ip2 = (retried && ip == ntohl(h->next.ip[0]) &&
292 p == ntohs(h->next.port)) ? ntohl(h->next.ip[1])
293 : ip2_from;
294 while (!after(ip2, ip2_to)) {
295 e.ip[1] = htonl(ip2);
296 ip2_last = ip_set_range_to_cidr(ip2, ip2_to,
297 &cidr2);
298 e.cidr[1] = cidr2;
299 ret = adtfn(set, &e, &ext, &ext, flags);
300 if (ret && !ip_set_eexist(ret, flags))
301 return ret;
302 else
303 ret = 0;
304 ip2 = ip2_last + 1;
305 }
306 }
307 ip = ip_last + 1;
308 }
309 return ret;
310}
311
312/* IPv6 variant */
313
314struct hash_netportnet6_elem {
315 union nf_inet_addr ip[2];
316 __be16 port;
317 union {
318 u8 cidr[2];
319 u16 ccmp;
320 };
321 u8 nomatch:1;
322 u8 proto;
323};
324
325/* Common functions */
326
327static inline bool
328hash_netportnet6_data_equal(const struct hash_netportnet6_elem *ip1,
329 const struct hash_netportnet6_elem *ip2,
330 u32 *multi)
331{
332 return ipv6_addr_equal(&ip1->ip[0].in6, &ip2->ip[0].in6) &&
333 ipv6_addr_equal(&ip1->ip[1].in6, &ip2->ip[1].in6) &&
334 ip1->ccmp == ip2->ccmp &&
335 ip1->port == ip2->port &&
336 ip1->proto == ip2->proto;
337}
338
339static inline int
340hash_netportnet6_do_data_match(const struct hash_netportnet6_elem *elem)
341{
342 return elem->nomatch ? -ENOTEMPTY : 1;
343}
344
345static inline void
346hash_netportnet6_data_set_flags(struct hash_netportnet6_elem *elem, u32 flags)
347{
348 elem->nomatch = !!((flags >> 16) & IPSET_FLAG_NOMATCH);
349}
350
351static inline void
352hash_netportnet6_data_reset_flags(struct hash_netportnet6_elem *elem, u8 *flags)
353{
354 swap(*flags, elem->nomatch);
355}
356
357static inline void
358hash_netportnet6_data_reset_elem(struct hash_netportnet6_elem *elem,
359 struct hash_netportnet6_elem *orig)
360{
361 elem->ip[1] = orig->ip[1];
362}
363
364static inline void
365hash_netportnet6_data_netmask(struct hash_netportnet6_elem *elem,
366 u8 cidr, bool inner)
367{
368 if (inner) {
369 ip6_netmask(&elem->ip[1], cidr);
370 elem->cidr[1] = cidr;
371 } else {
372 ip6_netmask(&elem->ip[0], cidr);
373 elem->cidr[0] = cidr;
374 }
375}
376
377static bool
378hash_netportnet6_data_list(struct sk_buff *skb,
379 const struct hash_netportnet6_elem *data)
380{
381 u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
382
383 if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip[0].in6) ||
384 nla_put_ipaddr6(skb, IPSET_ATTR_IP2, &data->ip[1].in6) ||
385 nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
386 nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr[0]) ||
387 nla_put_u8(skb, IPSET_ATTR_CIDR2, data->cidr[1]) ||
388 nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
389 (flags &&
390 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
391 goto nla_put_failure;
392 return 0;
393
394nla_put_failure:
395 return 1;
396}
397
398static inline void
399hash_netportnet6_data_next(struct hash_netportnet4_elem *next,
400 const struct hash_netportnet6_elem *d)
401{
402 next->port = d->port;
403}
404
405#undef MTYPE
406#undef PF
407#undef HOST_MASK
408
409#define MTYPE hash_netportnet6
410#define PF 6
411#define HOST_MASK 128
412#define IP_SET_EMIT_CREATE
413#include "ip_set_hash_gen.h"
414
415static int
416hash_netportnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
417 const struct xt_action_param *par,
418 enum ipset_adt adt, struct ip_set_adt_opt *opt)
419{
420 const struct hash_netportnet *h = set->data;
421 ipset_adtfn adtfn = set->variant->adt[adt];
422 struct hash_netportnet6_elem e = {
423 .cidr[0] = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK),
424 .cidr[1] = IP_SET_INIT_CIDR(h->nets[0].cidr[1], HOST_MASK),
425 };
426 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
427
428 if (adt == IPSET_TEST)
429 e.ccmp = (HOST_MASK << (sizeof(u8) * 8)) | HOST_MASK;
430
431 if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
432 &e.port, &e.proto))
433 return -EINVAL;
434
435 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip[0].in6);
436 ip6addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &e.ip[1].in6);
437 ip6_netmask(&e.ip[0], e.cidr[0]);
438 ip6_netmask(&e.ip[1], e.cidr[1]);
439
440 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
441}
442
443static int
444hash_netportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
445 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
446{
447 const struct hash_netportnet *h = set->data;
448 ipset_adtfn adtfn = set->variant->adt[adt];
449 struct hash_netportnet6_elem e = { .cidr[0] = HOST_MASK,
450 .cidr[1] = HOST_MASK };
451 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
452 u32 port, port_to;
453 bool with_ports = false;
454 int ret;
455
456 if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
457 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
458 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
459 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
460 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
461 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
462 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
463 return -IPSET_ERR_PROTOCOL;
464 if (unlikely(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_IP2_TO]))
465 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED;
466
467 if (tb[IPSET_ATTR_LINENO])
468 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
469
470 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip[0]) ||
471 ip_set_get_ipaddr6(tb[IPSET_ATTR_IP2], &e.ip[1]) ||
472 ip_set_get_extensions(set, tb, &ext);
473 if (ret)
474 return ret;
475
476 if (tb[IPSET_ATTR_CIDR])
477 e.cidr[0] = nla_get_u8(tb[IPSET_ATTR_CIDR]);
478
479 if (tb[IPSET_ATTR_CIDR2])
480 e.cidr[1] = nla_get_u8(tb[IPSET_ATTR_CIDR2]);
481
482 if (unlikely(!e.cidr[0] || e.cidr[0] > HOST_MASK || !e.cidr[1] ||
483 e.cidr[1] > HOST_MASK))
484 return -IPSET_ERR_INVALID_CIDR;
485
486 ip6_netmask(&e.ip[0], e.cidr[0]);
487 ip6_netmask(&e.ip[1], e.cidr[1]);
488
489 if (tb[IPSET_ATTR_PORT])
490 e.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
491 else
492 return -IPSET_ERR_PROTOCOL;
493
494 if (tb[IPSET_ATTR_PROTO]) {
495 e.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
496 with_ports = ip_set_proto_with_ports(e.proto);
497
498 if (e.proto == 0)
499 return -IPSET_ERR_INVALID_PROTO;
500 } else
501 return -IPSET_ERR_MISSING_PROTO;
502
503 if (!(with_ports || e.proto == IPPROTO_ICMPV6))
504 e.port = 0;
505
506 if (tb[IPSET_ATTR_CADT_FLAGS]) {
507 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
508 if (cadt_flags & IPSET_FLAG_NOMATCH)
509 flags |= (IPSET_FLAG_NOMATCH << 16);
510 }
511
512 if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
513 ret = adtfn(set, &e, &ext, &ext, flags);
514 return ip_set_enomatch(ret, flags, adt, set) ? -ret :
515 ip_set_eexist(ret, flags) ? 0 : ret;
516 }
517
518 port = ntohs(e.port);
519 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
520 if (port > port_to)
521 swap(port, port_to);
522
523 if (retried)
524 port = ntohs(h->next.port);
525 for (; port <= port_to; port++) {
526 e.port = htons(port);
527 ret = adtfn(set, &e, &ext, &ext, flags);
528
529 if (ret && !ip_set_eexist(ret, flags))
530 return ret;
531 else
532 ret = 0;
533 }
534 return ret;
535}
536
537static struct ip_set_type hash_netportnet_type __read_mostly = {
538 .name = "hash:net,port,net",
539 .protocol = IPSET_PROTOCOL,
540 .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2 |
541 IPSET_TYPE_NOMATCH,
542 .dimension = IPSET_DIM_THREE,
543 .family = NFPROTO_UNSPEC,
544 .revision_min = IPSET_TYPE_REV_MIN,
545 .revision_max = IPSET_TYPE_REV_MAX,
546 .create = hash_netportnet_create,
547 .create_policy = {
548 [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
549 [IPSET_ATTR_MAXELEM] = { .type = NLA_U32 },
550 [IPSET_ATTR_PROBES] = { .type = NLA_U8 },
551 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 },
552 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
553 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
554 },
555 .adt_policy = {
556 [IPSET_ATTR_IP] = { .type = NLA_NESTED },
557 [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED },
558 [IPSET_ATTR_IP2] = { .type = NLA_NESTED },
559 [IPSET_ATTR_IP2_TO] = { .type = NLA_NESTED },
560 [IPSET_ATTR_PORT] = { .type = NLA_U16 },
561 [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 },
562 [IPSET_ATTR_CIDR] = { .type = NLA_U8 },
563 [IPSET_ATTR_CIDR2] = { .type = NLA_U8 },
564 [IPSET_ATTR_PROTO] = { .type = NLA_U8 },
565 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
566 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
567 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
568 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
569 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
570 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
571 },
572 .me = THIS_MODULE,
573};
574
575static int __init
576hash_netportnet_init(void)
577{
578 return ip_set_type_register(&hash_netportnet_type);
579}
580
581static void __exit
582hash_netportnet_fini(void)
583{
584 ip_set_type_unregister(&hash_netportnet_type);
585}
586
587module_init(hash_netportnet_init);
588module_exit(hash_netportnet_fini);
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c
index 979b8c90e422..ec6f6d15dded 100644
--- a/net/netfilter/ipset/ip_set_list_set.c
+++ b/net/netfilter/ipset/ip_set_list_set.c
@@ -15,12 +15,13 @@
15#include <linux/netfilter/ipset/ip_set.h> 15#include <linux/netfilter/ipset/ip_set.h>
16#include <linux/netfilter/ipset/ip_set_list.h> 16#include <linux/netfilter/ipset/ip_set_list.h>
17 17
18#define REVISION_MIN 0 18#define IPSET_TYPE_REV_MIN 0
19#define REVISION_MAX 1 /* Counters support added */ 19/* 1 Counters support added */
20#define IPSET_TYPE_REV_MAX 2 /* Comments support added */
20 21
21MODULE_LICENSE("GPL"); 22MODULE_LICENSE("GPL");
22MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 23MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
23IP_SET_MODULE_DESC("list:set", REVISION_MIN, REVISION_MAX); 24IP_SET_MODULE_DESC("list:set", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
24MODULE_ALIAS("ip_set_list:set"); 25MODULE_ALIAS("ip_set_list:set");
25 26
26/* Member elements */ 27/* Member elements */
@@ -28,28 +29,6 @@ struct set_elem {
28 ip_set_id_t id; 29 ip_set_id_t id;
29}; 30};
30 31
31struct sett_elem {
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;
50 unsigned long timeout;
51};
52
53struct set_adt_elem { 32struct set_adt_elem {
54 ip_set_id_t id; 33 ip_set_id_t id;
55 ip_set_id_t refid; 34 ip_set_id_t refid;
@@ -58,24 +37,14 @@ struct set_adt_elem {
58 37
59/* Type structure */ 38/* Type structure */
60struct list_set { 39struct list_set {
61 size_t dsize; /* element size */
62 size_t offset[IPSET_OFFSET_MAX]; /* Offsets to extensions */
63 u32 size; /* size of set list array */ 40 u32 size; /* size of set list array */
64 u32 timeout; /* timeout value */
65 struct timer_list gc; /* garbage collection */ 41 struct timer_list gc; /* garbage collection */
42 struct net *net; /* namespace */
66 struct set_elem members[0]; /* the set members */ 43 struct set_elem members[0]; /* the set members */
67}; 44};
68 45
69static inline struct set_elem * 46#define list_set_elem(set, map, id) \
70list_set_elem(const struct list_set *map, u32 id) 47 (struct set_elem *)((void *)(map)->members + (id) * (set)->dsize)
71{
72 return (struct set_elem *)((void *)map->members + id * map->dsize);
73}
74
75#define ext_timeout(e, m) \
76(unsigned long *)((void *)(e) + (m)->offset[IPSET_OFFSET_TIMEOUT])
77#define ext_counter(e, m) \
78(struct ip_set_counter *)((void *)(e) + (m)->offset[IPSET_OFFSET_COUNTER])
79 48
80static int 49static int
81list_set_ktest(struct ip_set *set, const struct sk_buff *skb, 50list_set_ktest(struct ip_set *set, const struct sk_buff *skb,
@@ -92,16 +61,16 @@ list_set_ktest(struct ip_set *set, const struct sk_buff *skb,
92 if (opt->cmdflags & IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE) 61 if (opt->cmdflags & IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE)
93 opt->cmdflags &= ~IPSET_FLAG_SKIP_COUNTER_UPDATE; 62 opt->cmdflags &= ~IPSET_FLAG_SKIP_COUNTER_UPDATE;
94 for (i = 0; i < map->size; i++) { 63 for (i = 0; i < map->size; i++) {
95 e = list_set_elem(map, i); 64 e = list_set_elem(set, map, i);
96 if (e->id == IPSET_INVALID_ID) 65 if (e->id == IPSET_INVALID_ID)
97 return 0; 66 return 0;
98 if (SET_WITH_TIMEOUT(set) && 67 if (SET_WITH_TIMEOUT(set) &&
99 ip_set_timeout_expired(ext_timeout(e, map))) 68 ip_set_timeout_expired(ext_timeout(e, set)))
100 continue; 69 continue;
101 ret = ip_set_test(e->id, skb, par, opt); 70 ret = ip_set_test(e->id, skb, par, opt);
102 if (ret > 0) { 71 if (ret > 0) {
103 if (SET_WITH_COUNTER(set)) 72 if (SET_WITH_COUNTER(set))
104 ip_set_update_counter(ext_counter(e, map), 73 ip_set_update_counter(ext_counter(e, set),
105 ext, &opt->ext, 74 ext, &opt->ext,
106 cmdflags); 75 cmdflags);
107 return ret; 76 return ret;
@@ -121,11 +90,11 @@ list_set_kadd(struct ip_set *set, const struct sk_buff *skb,
121 int ret; 90 int ret;
122 91
123 for (i = 0; i < map->size; i++) { 92 for (i = 0; i < map->size; i++) {
124 e = list_set_elem(map, i); 93 e = list_set_elem(set, map, i);
125 if (e->id == IPSET_INVALID_ID) 94 if (e->id == IPSET_INVALID_ID)
126 return 0; 95 return 0;
127 if (SET_WITH_TIMEOUT(set) && 96 if (SET_WITH_TIMEOUT(set) &&
128 ip_set_timeout_expired(ext_timeout(e, map))) 97 ip_set_timeout_expired(ext_timeout(e, set)))
129 continue; 98 continue;
130 ret = ip_set_add(e->id, skb, par, opt); 99 ret = ip_set_add(e->id, skb, par, opt);
131 if (ret == 0) 100 if (ret == 0)
@@ -145,11 +114,11 @@ list_set_kdel(struct ip_set *set, const struct sk_buff *skb,
145 int ret; 114 int ret;
146 115
147 for (i = 0; i < map->size; i++) { 116 for (i = 0; i < map->size; i++) {
148 e = list_set_elem(map, i); 117 e = list_set_elem(set, map, i);
149 if (e->id == IPSET_INVALID_ID) 118 if (e->id == IPSET_INVALID_ID)
150 return 0; 119 return 0;
151 if (SET_WITH_TIMEOUT(set) && 120 if (SET_WITH_TIMEOUT(set) &&
152 ip_set_timeout_expired(ext_timeout(e, map))) 121 ip_set_timeout_expired(ext_timeout(e, set)))
153 continue; 122 continue;
154 ret = ip_set_del(e->id, skb, par, opt); 123 ret = ip_set_del(e->id, skb, par, opt);
155 if (ret == 0) 124 if (ret == 0)
@@ -163,8 +132,7 @@ list_set_kadt(struct ip_set *set, const struct sk_buff *skb,
163 const struct xt_action_param *par, 132 const struct xt_action_param *par,
164 enum ipset_adt adt, struct ip_set_adt_opt *opt) 133 enum ipset_adt adt, struct ip_set_adt_opt *opt)
165{ 134{
166 struct list_set *map = set->data; 135 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
167 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map);
168 136
169 switch (adt) { 137 switch (adt) {
170 case IPSET_TEST: 138 case IPSET_TEST:
@@ -188,10 +156,10 @@ id_eq(const struct ip_set *set, u32 i, ip_set_id_t id)
188 if (i >= map->size) 156 if (i >= map->size)
189 return 0; 157 return 0;
190 158
191 e = list_set_elem(map, i); 159 e = list_set_elem(set, map, i);
192 return !!(e->id == id && 160 return !!(e->id == id &&
193 !(SET_WITH_TIMEOUT(set) && 161 !(SET_WITH_TIMEOUT(set) &&
194 ip_set_timeout_expired(ext_timeout(e, map)))); 162 ip_set_timeout_expired(ext_timeout(e, set))));
195} 163}
196 164
197static int 165static int
@@ -199,28 +167,36 @@ list_set_add(struct ip_set *set, u32 i, struct set_adt_elem *d,
199 const struct ip_set_ext *ext) 167 const struct ip_set_ext *ext)
200{ 168{
201 struct list_set *map = set->data; 169 struct list_set *map = set->data;
202 struct set_elem *e = list_set_elem(map, i); 170 struct set_elem *e = list_set_elem(set, map, i);
203 171
204 if (e->id != IPSET_INVALID_ID) { 172 if (e->id != IPSET_INVALID_ID) {
205 if (i == map->size - 1) 173 if (i == map->size - 1) {
206 /* Last element replaced: e.g. add new,before,last */ 174 /* Last element replaced: e.g. add new,before,last */
207 ip_set_put_byindex(e->id); 175 ip_set_put_byindex(map->net, e->id);
208 else { 176 ip_set_ext_destroy(set, e);
209 struct set_elem *x = list_set_elem(map, map->size - 1); 177 } else {
178 struct set_elem *x = list_set_elem(set, map,
179 map->size - 1);
210 180
211 /* Last element pushed off */ 181 /* Last element pushed off */
212 if (x->id != IPSET_INVALID_ID) 182 if (x->id != IPSET_INVALID_ID) {
213 ip_set_put_byindex(x->id); 183 ip_set_put_byindex(map->net, x->id);
214 memmove(list_set_elem(map, i + 1), e, 184 ip_set_ext_destroy(set, x);
215 map->dsize * (map->size - (i + 1))); 185 }
186 memmove(list_set_elem(set, map, i + 1), e,
187 set->dsize * (map->size - (i + 1)));
188 /* Extensions must be initialized to zero */
189 memset(e, 0, set->dsize);
216 } 190 }
217 } 191 }
218 192
219 e->id = d->id; 193 e->id = d->id;
220 if (SET_WITH_TIMEOUT(set)) 194 if (SET_WITH_TIMEOUT(set))
221 ip_set_timeout_set(ext_timeout(e, map), ext->timeout); 195 ip_set_timeout_set(ext_timeout(e, set), ext->timeout);
222 if (SET_WITH_COUNTER(set)) 196 if (SET_WITH_COUNTER(set))
223 ip_set_init_counter(ext_counter(e, map), ext); 197 ip_set_init_counter(ext_counter(e, set), ext);
198 if (SET_WITH_COMMENT(set))
199 ip_set_init_comment(ext_comment(e, set), ext);
224 return 0; 200 return 0;
225} 201}
226 202
@@ -228,16 +204,17 @@ static int
228list_set_del(struct ip_set *set, u32 i) 204list_set_del(struct ip_set *set, u32 i)
229{ 205{
230 struct list_set *map = set->data; 206 struct list_set *map = set->data;
231 struct set_elem *e = list_set_elem(map, i); 207 struct set_elem *e = list_set_elem(set, map, i);
232 208
233 ip_set_put_byindex(e->id); 209 ip_set_put_byindex(map->net, e->id);
210 ip_set_ext_destroy(set, e);
234 211
235 if (i < map->size - 1) 212 if (i < map->size - 1)
236 memmove(e, list_set_elem(map, i + 1), 213 memmove(e, list_set_elem(set, map, i + 1),
237 map->dsize * (map->size - (i + 1))); 214 set->dsize * (map->size - (i + 1)));
238 215
239 /* Last element */ 216 /* Last element */
240 e = list_set_elem(map, map->size - 1); 217 e = list_set_elem(set, map, map->size - 1);
241 e->id = IPSET_INVALID_ID; 218 e->id = IPSET_INVALID_ID;
242 return 0; 219 return 0;
243} 220}
@@ -247,13 +224,16 @@ set_cleanup_entries(struct ip_set *set)
247{ 224{
248 struct list_set *map = set->data; 225 struct list_set *map = set->data;
249 struct set_elem *e; 226 struct set_elem *e;
250 u32 i; 227 u32 i = 0;
251 228
252 for (i = 0; i < map->size; i++) { 229 while (i < map->size) {
253 e = list_set_elem(map, i); 230 e = list_set_elem(set, map, i);
254 if (e->id != IPSET_INVALID_ID && 231 if (e->id != IPSET_INVALID_ID &&
255 ip_set_timeout_expired(ext_timeout(e, map))) 232 ip_set_timeout_expired(ext_timeout(e, set)))
256 list_set_del(set, i); 233 list_set_del(set, i);
234 /* Check element moved to position i in next loop */
235 else
236 i++;
257 } 237 }
258} 238}
259 239
@@ -268,11 +248,11 @@ list_set_utest(struct ip_set *set, void *value, const struct ip_set_ext *ext,
268 int ret; 248 int ret;
269 249
270 for (i = 0; i < map->size; i++) { 250 for (i = 0; i < map->size; i++) {
271 e = list_set_elem(map, i); 251 e = list_set_elem(set, map, i);
272 if (e->id == IPSET_INVALID_ID) 252 if (e->id == IPSET_INVALID_ID)
273 return 0; 253 return 0;
274 else if (SET_WITH_TIMEOUT(set) && 254 else if (SET_WITH_TIMEOUT(set) &&
275 ip_set_timeout_expired(ext_timeout(e, map))) 255 ip_set_timeout_expired(ext_timeout(e, set)))
276 continue; 256 continue;
277 else if (e->id != d->id) 257 else if (e->id != d->id)
278 continue; 258 continue;
@@ -299,14 +279,14 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
299 bool flag_exist = flags & IPSET_FLAG_EXIST; 279 bool flag_exist = flags & IPSET_FLAG_EXIST;
300 u32 i, ret = 0; 280 u32 i, ret = 0;
301 281
282 if (SET_WITH_TIMEOUT(set))
283 set_cleanup_entries(set);
284
302 /* Check already added element */ 285 /* Check already added element */
303 for (i = 0; i < map->size; i++) { 286 for (i = 0; i < map->size; i++) {
304 e = list_set_elem(map, i); 287 e = list_set_elem(set, map, i);
305 if (e->id == IPSET_INVALID_ID) 288 if (e->id == IPSET_INVALID_ID)
306 goto insert; 289 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) 290 else if (e->id != d->id)
311 continue; 291 continue;
312 292
@@ -319,18 +299,22 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
319 /* Can't re-add */ 299 /* Can't re-add */
320 return -IPSET_ERR_EXIST; 300 return -IPSET_ERR_EXIST;
321 /* Update extensions */ 301 /* Update extensions */
302 ip_set_ext_destroy(set, e);
303
322 if (SET_WITH_TIMEOUT(set)) 304 if (SET_WITH_TIMEOUT(set))
323 ip_set_timeout_set(ext_timeout(e, map), ext->timeout); 305 ip_set_timeout_set(ext_timeout(e, set), ext->timeout);
324 if (SET_WITH_COUNTER(set)) 306 if (SET_WITH_COUNTER(set))
325 ip_set_init_counter(ext_counter(e, map), ext); 307 ip_set_init_counter(ext_counter(e, set), ext);
308 if (SET_WITH_COMMENT(set))
309 ip_set_init_comment(ext_comment(e, set), ext);
326 /* Set is already added to the list */ 310 /* Set is already added to the list */
327 ip_set_put_byindex(d->id); 311 ip_set_put_byindex(map->net, d->id);
328 return 0; 312 return 0;
329 } 313 }
330insert: 314insert:
331 ret = -IPSET_ERR_LIST_FULL; 315 ret = -IPSET_ERR_LIST_FULL;
332 for (i = 0; i < map->size && ret == -IPSET_ERR_LIST_FULL; i++) { 316 for (i = 0; i < map->size && ret == -IPSET_ERR_LIST_FULL; i++) {
333 e = list_set_elem(map, i); 317 e = list_set_elem(set, map, i);
334 if (e->id == IPSET_INVALID_ID) 318 if (e->id == IPSET_INVALID_ID)
335 ret = d->before != 0 ? -IPSET_ERR_REF_EXIST 319 ret = d->before != 0 ? -IPSET_ERR_REF_EXIST
336 : list_set_add(set, i, d, ext); 320 : list_set_add(set, i, d, ext);
@@ -355,12 +339,12 @@ list_set_udel(struct ip_set *set, void *value, const struct ip_set_ext *ext,
355 u32 i; 339 u32 i;
356 340
357 for (i = 0; i < map->size; i++) { 341 for (i = 0; i < map->size; i++) {
358 e = list_set_elem(map, i); 342 e = list_set_elem(set, map, i);
359 if (e->id == IPSET_INVALID_ID) 343 if (e->id == IPSET_INVALID_ID)
360 return d->before != 0 ? -IPSET_ERR_REF_EXIST 344 return d->before != 0 ? -IPSET_ERR_REF_EXIST
361 : -IPSET_ERR_EXIST; 345 : -IPSET_ERR_EXIST;
362 else if (SET_WITH_TIMEOUT(set) && 346 else if (SET_WITH_TIMEOUT(set) &&
363 ip_set_timeout_expired(ext_timeout(e, map))) 347 ip_set_timeout_expired(ext_timeout(e, set)))
364 continue; 348 continue;
365 else if (e->id != d->id) 349 else if (e->id != d->id)
366 continue; 350 continue;
@@ -386,7 +370,7 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
386 struct list_set *map = set->data; 370 struct list_set *map = set->data;
387 ipset_adtfn adtfn = set->variant->adt[adt]; 371 ipset_adtfn adtfn = set->variant->adt[adt];
388 struct set_adt_elem e = { .refid = IPSET_INVALID_ID }; 372 struct set_adt_elem e = { .refid = IPSET_INVALID_ID };
389 struct ip_set_ext ext = IP_SET_INIT_UEXT(map); 373 struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
390 struct ip_set *s; 374 struct ip_set *s;
391 int ret = 0; 375 int ret = 0;
392 376
@@ -403,7 +387,7 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
403 ret = ip_set_get_extensions(set, tb, &ext); 387 ret = ip_set_get_extensions(set, tb, &ext);
404 if (ret) 388 if (ret)
405 return ret; 389 return ret;
406 e.id = ip_set_get_byname(nla_data(tb[IPSET_ATTR_NAME]), &s); 390 e.id = ip_set_get_byname(map->net, nla_data(tb[IPSET_ATTR_NAME]), &s);
407 if (e.id == IPSET_INVALID_ID) 391 if (e.id == IPSET_INVALID_ID)
408 return -IPSET_ERR_NAME; 392 return -IPSET_ERR_NAME;
409 /* "Loop detection" */ 393 /* "Loop detection" */
@@ -423,7 +407,8 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
423 } 407 }
424 408
425 if (tb[IPSET_ATTR_NAMEREF]) { 409 if (tb[IPSET_ATTR_NAMEREF]) {
426 e.refid = ip_set_get_byname(nla_data(tb[IPSET_ATTR_NAMEREF]), 410 e.refid = ip_set_get_byname(map->net,
411 nla_data(tb[IPSET_ATTR_NAMEREF]),
427 &s); 412 &s);
428 if (e.refid == IPSET_INVALID_ID) { 413 if (e.refid == IPSET_INVALID_ID) {
429 ret = -IPSET_ERR_NAMEREF; 414 ret = -IPSET_ERR_NAMEREF;
@@ -439,9 +424,9 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
439 424
440finish: 425finish:
441 if (e.refid != IPSET_INVALID_ID) 426 if (e.refid != IPSET_INVALID_ID)
442 ip_set_put_byindex(e.refid); 427 ip_set_put_byindex(map->net, e.refid);
443 if (adt != IPSET_ADD || ret) 428 if (adt != IPSET_ADD || ret)
444 ip_set_put_byindex(e.id); 429 ip_set_put_byindex(map->net, e.id);
445 430
446 return ip_set_eexist(ret, flags) ? 0 : ret; 431 return ip_set_eexist(ret, flags) ? 0 : ret;
447} 432}
@@ -454,9 +439,10 @@ list_set_flush(struct ip_set *set)
454 u32 i; 439 u32 i;
455 440
456 for (i = 0; i < map->size; i++) { 441 for (i = 0; i < map->size; i++) {
457 e = list_set_elem(map, i); 442 e = list_set_elem(set, map, i);
458 if (e->id != IPSET_INVALID_ID) { 443 if (e->id != IPSET_INVALID_ID) {
459 ip_set_put_byindex(e->id); 444 ip_set_put_byindex(map->net, e->id);
445 ip_set_ext_destroy(set, e);
460 e->id = IPSET_INVALID_ID; 446 e->id = IPSET_INVALID_ID;
461 } 447 }
462 } 448 }
@@ -485,14 +471,11 @@ list_set_head(struct ip_set *set, struct sk_buff *skb)
485 if (!nested) 471 if (!nested)
486 goto nla_put_failure; 472 goto nla_put_failure;
487 if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) || 473 if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) ||
488 (SET_WITH_TIMEOUT(set) &&
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))) ||
493 nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || 474 nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
494 nla_put_net32(skb, IPSET_ATTR_MEMSIZE, 475 nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
495 htonl(sizeof(*map) + map->size * map->dsize))) 476 htonl(sizeof(*map) + map->size * set->dsize)))
477 goto nla_put_failure;
478 if (unlikely(ip_set_put_flags(skb, set)))
496 goto nla_put_failure; 479 goto nla_put_failure;
497 ipset_nest_end(skb, nested); 480 ipset_nest_end(skb, nested);
498 481
@@ -515,11 +498,11 @@ list_set_list(const struct ip_set *set,
515 return -EMSGSIZE; 498 return -EMSGSIZE;
516 for (; cb->args[2] < map->size; cb->args[2]++) { 499 for (; cb->args[2] < map->size; cb->args[2]++) {
517 i = cb->args[2]; 500 i = cb->args[2];
518 e = list_set_elem(map, i); 501 e = list_set_elem(set, map, i);
519 if (e->id == IPSET_INVALID_ID) 502 if (e->id == IPSET_INVALID_ID)
520 goto finish; 503 goto finish;
521 if (SET_WITH_TIMEOUT(set) && 504 if (SET_WITH_TIMEOUT(set) &&
522 ip_set_timeout_expired(ext_timeout(e, map))) 505 ip_set_timeout_expired(ext_timeout(e, set)))
523 continue; 506 continue;
524 nested = ipset_nest_start(skb, IPSET_ATTR_DATA); 507 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
525 if (!nested) { 508 if (!nested) {
@@ -530,15 +513,9 @@ list_set_list(const struct ip_set *set,
530 goto nla_put_failure; 513 goto nla_put_failure;
531 } 514 }
532 if (nla_put_string(skb, IPSET_ATTR_NAME, 515 if (nla_put_string(skb, IPSET_ATTR_NAME,
533 ip_set_name_byindex(e->id))) 516 ip_set_name_byindex(map->net, e->id)))
534 goto nla_put_failure;
535 if (SET_WITH_TIMEOUT(set) &&
536 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
537 htonl(ip_set_timeout_get(
538 ext_timeout(e, map)))))
539 goto nla_put_failure; 517 goto nla_put_failure;
540 if (SET_WITH_COUNTER(set) && 518 if (ip_set_put_extensions(skb, set, e, true))
541 ip_set_put_counter(skb, ext_counter(e, map)))
542 goto nla_put_failure; 519 goto nla_put_failure;
543 ipset_nest_end(skb, nested); 520 ipset_nest_end(skb, nested);
544 } 521 }
@@ -550,11 +527,11 @@ finish:
550 527
551nla_put_failure: 528nla_put_failure:
552 nla_nest_cancel(skb, nested); 529 nla_nest_cancel(skb, nested);
553 ipset_nest_end(skb, atd);
554 if (unlikely(i == first)) { 530 if (unlikely(i == first)) {
555 cb->args[2] = 0; 531 cb->args[2] = 0;
556 return -EMSGSIZE; 532 return -EMSGSIZE;
557 } 533 }
534 ipset_nest_end(skb, atd);
558 return 0; 535 return 0;
559} 536}
560 537
@@ -565,7 +542,7 @@ list_set_same_set(const struct ip_set *a, const struct ip_set *b)
565 const struct list_set *y = b->data; 542 const struct list_set *y = b->data;
566 543
567 return x->size == y->size && 544 return x->size == y->size &&
568 x->timeout == y->timeout && 545 a->timeout == b->timeout &&
569 a->extensions == b->extensions; 546 a->extensions == b->extensions;
570} 547}
571 548
@@ -594,7 +571,7 @@ list_set_gc(unsigned long ul_set)
594 set_cleanup_entries(set); 571 set_cleanup_entries(set);
595 write_unlock_bh(&set->lock); 572 write_unlock_bh(&set->lock);
596 573
597 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; 574 map->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
598 add_timer(&map->gc); 575 add_timer(&map->gc);
599} 576}
600 577
@@ -606,43 +583,40 @@ list_set_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
606 init_timer(&map->gc); 583 init_timer(&map->gc);
607 map->gc.data = (unsigned long) set; 584 map->gc.data = (unsigned long) set;
608 map->gc.function = gc; 585 map->gc.function = gc;
609 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; 586 map->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
610 add_timer(&map->gc); 587 add_timer(&map->gc);
611} 588}
612 589
613/* Create list:set type of sets */ 590/* Create list:set type of sets */
614 591
615static struct list_set * 592static bool
616init_list_set(struct ip_set *set, u32 size, size_t dsize, 593init_list_set(struct net *net, struct ip_set *set, u32 size)
617 unsigned long timeout)
618{ 594{
619 struct list_set *map; 595 struct list_set *map;
620 struct set_elem *e; 596 struct set_elem *e;
621 u32 i; 597 u32 i;
622 598
623 map = kzalloc(sizeof(*map) + size * dsize, GFP_KERNEL); 599 map = kzalloc(sizeof(*map) + size * set->dsize, GFP_KERNEL);
624 if (!map) 600 if (!map)
625 return NULL; 601 return false;
626 602
627 map->size = size; 603 map->size = size;
628 map->dsize = dsize; 604 map->net = net;
629 map->timeout = timeout;
630 set->data = map; 605 set->data = map;
631 606
632 for (i = 0; i < size; i++) { 607 for (i = 0; i < size; i++) {
633 e = list_set_elem(map, i); 608 e = list_set_elem(set, map, i);
634 e->id = IPSET_INVALID_ID; 609 e->id = IPSET_INVALID_ID;
635 } 610 }
636 611
637 return map; 612 return true;
638} 613}
639 614
640static int 615static int
641list_set_create(struct ip_set *set, struct nlattr *tb[], u32 flags) 616list_set_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
617 u32 flags)
642{ 618{
643 struct list_set *map; 619 u32 size = IP_SET_LIST_DEFAULT_SIZE;
644 u32 size = IP_SET_LIST_DEFAULT_SIZE, cadt_flags = 0;
645 unsigned long timeout = 0;
646 620
647 if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_SIZE) || 621 if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_SIZE) ||
648 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 622 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
@@ -654,45 +628,13 @@ list_set_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
654 if (size < IP_SET_LIST_MIN_SIZE) 628 if (size < IP_SET_LIST_MIN_SIZE)
655 size = IP_SET_LIST_MIN_SIZE; 629 size = IP_SET_LIST_MIN_SIZE;
656 630
657 if (tb[IPSET_ATTR_CADT_FLAGS])
658 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
659 if (tb[IPSET_ATTR_TIMEOUT])
660 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
661 set->variant = &set_variant; 631 set->variant = &set_variant;
662 if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) { 632 set->dsize = ip_set_elem_len(set, tb, sizeof(struct set_elem));
663 set->extensions |= IPSET_EXT_COUNTER; 633 if (!init_list_set(net, set, size))
664 if (tb[IPSET_ATTR_TIMEOUT]) { 634 return -ENOMEM;
665 map = init_list_set(set, size, 635 if (tb[IPSET_ATTR_TIMEOUT]) {
666 sizeof(struct setct_elem), timeout); 636 set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_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)
687 return -ENOMEM;
688 set->extensions |= IPSET_EXT_TIMEOUT;
689 map->offset[IPSET_OFFSET_TIMEOUT] =
690 offsetof(struct sett_elem, timeout);
691 list_set_gc_init(set, list_set_gc); 637 list_set_gc_init(set, list_set_gc);
692 } else {
693 map = init_list_set(set, size, sizeof(struct set_elem), 0);
694 if (!map)
695 return -ENOMEM;
696 } 638 }
697 return 0; 639 return 0;
698} 640}
@@ -703,8 +645,8 @@ static struct ip_set_type list_set_type __read_mostly = {
703 .features = IPSET_TYPE_NAME | IPSET_DUMP_LAST, 645 .features = IPSET_TYPE_NAME | IPSET_DUMP_LAST,
704 .dimension = IPSET_DIM_ONE, 646 .dimension = IPSET_DIM_ONE,
705 .family = NFPROTO_UNSPEC, 647 .family = NFPROTO_UNSPEC,
706 .revision_min = REVISION_MIN, 648 .revision_min = IPSET_TYPE_REV_MIN,
707 .revision_max = REVISION_MAX, 649 .revision_max = IPSET_TYPE_REV_MAX,
708 .create = list_set_create, 650 .create = list_set_create,
709 .create_policy = { 651 .create_policy = {
710 [IPSET_ATTR_SIZE] = { .type = NLA_U32 }, 652 [IPSET_ATTR_SIZE] = { .type = NLA_U32 },
@@ -721,6 +663,7 @@ static struct ip_set_type list_set_type __read_mostly = {
721 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 663 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
722 [IPSET_ATTR_BYTES] = { .type = NLA_U64 }, 664 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
723 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, 665 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
666 [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
724 }, 667 },
725 .me = THIS_MODULE, 668 .me = THIS_MODULE,
726}; 669};
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index e0c4373b4747..466410eaa482 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -52,66 +52,8 @@ module_param(sip_direct_media, int, 0600);
52MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling " 52MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling "
53 "endpoints only (default 1)"); 53 "endpoints only (default 1)");
54 54
55unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, unsigned int protoff, 55const struct nf_nat_sip_hooks *nf_nat_sip_hooks;
56 unsigned int dataoff, const char **dptr, 56EXPORT_SYMBOL_GPL(nf_nat_sip_hooks);
57 unsigned int *datalen) __read_mostly;
58EXPORT_SYMBOL_GPL(nf_nat_sip_hook);
59
60void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb, unsigned int protoff,
61 s16 off) __read_mostly;
62EXPORT_SYMBOL_GPL(nf_nat_sip_seq_adjust_hook);
63
64unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb,
65 unsigned int protoff,
66 unsigned int dataoff,
67 const char **dptr,
68 unsigned int *datalen,
69 struct nf_conntrack_expect *exp,
70 unsigned int matchoff,
71 unsigned int matchlen) __read_mostly;
72EXPORT_SYMBOL_GPL(nf_nat_sip_expect_hook);
73
74unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb, unsigned int protoff,
75 unsigned int dataoff,
76 const char **dptr,
77 unsigned int *datalen,
78 unsigned int sdpoff,
79 enum sdp_header_types type,
80 enum sdp_header_types term,
81 const union nf_inet_addr *addr)
82 __read_mostly;
83EXPORT_SYMBOL_GPL(nf_nat_sdp_addr_hook);
84
85unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb, unsigned int protoff,
86 unsigned int dataoff,
87 const char **dptr,
88 unsigned int *datalen,
89 unsigned int matchoff,
90 unsigned int matchlen,
91 u_int16_t port) __read_mostly;
92EXPORT_SYMBOL_GPL(nf_nat_sdp_port_hook);
93
94unsigned int (*nf_nat_sdp_session_hook)(struct sk_buff *skb,
95 unsigned int protoff,
96 unsigned int dataoff,
97 const char **dptr,
98 unsigned int *datalen,
99 unsigned int sdpoff,
100 const union nf_inet_addr *addr)
101 __read_mostly;
102EXPORT_SYMBOL_GPL(nf_nat_sdp_session_hook);
103
104unsigned int (*nf_nat_sdp_media_hook)(struct sk_buff *skb, unsigned int protoff,
105 unsigned int dataoff,
106 const char **dptr,
107 unsigned int *datalen,
108 struct nf_conntrack_expect *rtp_exp,
109 struct nf_conntrack_expect *rtcp_exp,
110 unsigned int mediaoff,
111 unsigned int medialen,
112 union nf_inet_addr *rtp_addr)
113 __read_mostly;
114EXPORT_SYMBOL_GPL(nf_nat_sdp_media_hook);
115 57
116static int string_len(const struct nf_conn *ct, const char *dptr, 58static int string_len(const struct nf_conn *ct, const char *dptr,
117 const char *limit, int *shift) 59 const char *limit, int *shift)
@@ -914,8 +856,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,
914 int direct_rtp = 0, skip_expect = 0, ret = NF_DROP; 856 int direct_rtp = 0, skip_expect = 0, ret = NF_DROP;
915 u_int16_t base_port; 857 u_int16_t base_port;
916 __be16 rtp_port, rtcp_port; 858 __be16 rtp_port, rtcp_port;
917 typeof(nf_nat_sdp_port_hook) nf_nat_sdp_port; 859 const struct nf_nat_sip_hooks *hooks;
918 typeof(nf_nat_sdp_media_hook) nf_nat_sdp_media;
919 860
920 saddr = NULL; 861 saddr = NULL;
921 if (sip_direct_media) { 862 if (sip_direct_media) {
@@ -966,22 +907,23 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,
966#endif 907#endif
967 skip_expect = 1; 908 skip_expect = 1;
968 } while (!skip_expect); 909 } while (!skip_expect);
969 rcu_read_unlock();
970 910
971 base_port = ntohs(tuple.dst.u.udp.port) & ~1; 911 base_port = ntohs(tuple.dst.u.udp.port) & ~1;
972 rtp_port = htons(base_port); 912 rtp_port = htons(base_port);
973 rtcp_port = htons(base_port + 1); 913 rtcp_port = htons(base_port + 1);
974 914
975 if (direct_rtp) { 915 if (direct_rtp) {
976 nf_nat_sdp_port = rcu_dereference(nf_nat_sdp_port_hook); 916 hooks = rcu_dereference(nf_nat_sip_hooks);
977 if (nf_nat_sdp_port && 917 if (hooks &&
978 !nf_nat_sdp_port(skb, protoff, dataoff, dptr, datalen, 918 !hooks->sdp_port(skb, protoff, dataoff, dptr, datalen,
979 mediaoff, medialen, ntohs(rtp_port))) 919 mediaoff, medialen, ntohs(rtp_port)))
980 goto err1; 920 goto err1;
981 } 921 }
982 922
983 if (skip_expect) 923 if (skip_expect) {
924 rcu_read_unlock();
984 return NF_ACCEPT; 925 return NF_ACCEPT;
926 }
985 927
986 rtp_exp = nf_ct_expect_alloc(ct); 928 rtp_exp = nf_ct_expect_alloc(ct);
987 if (rtp_exp == NULL) 929 if (rtp_exp == NULL)
@@ -995,10 +937,10 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,
995 nf_ct_expect_init(rtcp_exp, class, nf_ct_l3num(ct), saddr, daddr, 937 nf_ct_expect_init(rtcp_exp, class, nf_ct_l3num(ct), saddr, daddr,
996 IPPROTO_UDP, NULL, &rtcp_port); 938 IPPROTO_UDP, NULL, &rtcp_port);
997 939
998 nf_nat_sdp_media = rcu_dereference(nf_nat_sdp_media_hook); 940 hooks = rcu_dereference(nf_nat_sip_hooks);
999 if (nf_nat_sdp_media && ct->status & IPS_NAT_MASK && !direct_rtp) 941 if (hooks && ct->status & IPS_NAT_MASK && !direct_rtp)
1000 ret = nf_nat_sdp_media(skb, protoff, dataoff, dptr, datalen, 942 ret = hooks->sdp_media(skb, protoff, dataoff, dptr,
1001 rtp_exp, rtcp_exp, 943 datalen, rtp_exp, rtcp_exp,
1002 mediaoff, medialen, daddr); 944 mediaoff, medialen, daddr);
1003 else { 945 else {
1004 if (nf_ct_expect_related(rtp_exp) == 0) { 946 if (nf_ct_expect_related(rtp_exp) == 0) {
@@ -1012,6 +954,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,
1012err2: 954err2:
1013 nf_ct_expect_put(rtp_exp); 955 nf_ct_expect_put(rtp_exp);
1014err1: 956err1:
957 rcu_read_unlock();
1015 return ret; 958 return ret;
1016} 959}
1017 960
@@ -1051,13 +994,12 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff,
1051 unsigned int caddr_len, maddr_len; 994 unsigned int caddr_len, maddr_len;
1052 unsigned int i; 995 unsigned int i;
1053 union nf_inet_addr caddr, maddr, rtp_addr; 996 union nf_inet_addr caddr, maddr, rtp_addr;
997 const struct nf_nat_sip_hooks *hooks;
1054 unsigned int port; 998 unsigned int port;
1055 const struct sdp_media_type *t; 999 const struct sdp_media_type *t;
1056 int ret = NF_ACCEPT; 1000 int ret = NF_ACCEPT;
1057 typeof(nf_nat_sdp_addr_hook) nf_nat_sdp_addr;
1058 typeof(nf_nat_sdp_session_hook) nf_nat_sdp_session;
1059 1001
1060 nf_nat_sdp_addr = rcu_dereference(nf_nat_sdp_addr_hook); 1002 hooks = rcu_dereference(nf_nat_sip_hooks);
1061 1003
1062 /* Find beginning of session description */ 1004 /* Find beginning of session description */
1063 if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen, 1005 if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen,
@@ -1125,10 +1067,11 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff,
1125 } 1067 }
1126 1068
1127 /* Update media connection address if present */ 1069 /* Update media connection address if present */
1128 if (maddr_len && nf_nat_sdp_addr && ct->status & IPS_NAT_MASK) { 1070 if (maddr_len && hooks && ct->status & IPS_NAT_MASK) {
1129 ret = nf_nat_sdp_addr(skb, protoff, dataoff, 1071 ret = hooks->sdp_addr(skb, protoff, dataoff,
1130 dptr, datalen, mediaoff, 1072 dptr, datalen, mediaoff,
1131 SDP_HDR_CONNECTION, SDP_HDR_MEDIA, 1073 SDP_HDR_CONNECTION,
1074 SDP_HDR_MEDIA,
1132 &rtp_addr); 1075 &rtp_addr);
1133 if (ret != NF_ACCEPT) { 1076 if (ret != NF_ACCEPT) {
1134 nf_ct_helper_log(skb, ct, "cannot mangle SDP"); 1077 nf_ct_helper_log(skb, ct, "cannot mangle SDP");
@@ -1139,10 +1082,11 @@ static int process_sdp(struct sk_buff *skb, unsigned int protoff,
1139 } 1082 }
1140 1083
1141 /* Update session connection and owner addresses */ 1084 /* Update session connection and owner addresses */
1142 nf_nat_sdp_session = rcu_dereference(nf_nat_sdp_session_hook); 1085 hooks = rcu_dereference(nf_nat_sip_hooks);
1143 if (nf_nat_sdp_session && ct->status & IPS_NAT_MASK) 1086 if (hooks && ct->status & IPS_NAT_MASK)
1144 ret = nf_nat_sdp_session(skb, protoff, dataoff, 1087 ret = hooks->sdp_session(skb, protoff, dataoff,
1145 dptr, datalen, sdpoff, &rtp_addr); 1088 dptr, datalen, sdpoff,
1089 &rtp_addr);
1146 1090
1147 return ret; 1091 return ret;
1148} 1092}
@@ -1242,11 +1186,11 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff,
1242 unsigned int matchoff, matchlen; 1186 unsigned int matchoff, matchlen;
1243 struct nf_conntrack_expect *exp; 1187 struct nf_conntrack_expect *exp;
1244 union nf_inet_addr *saddr, daddr; 1188 union nf_inet_addr *saddr, daddr;
1189 const struct nf_nat_sip_hooks *hooks;
1245 __be16 port; 1190 __be16 port;
1246 u8 proto; 1191 u8 proto;
1247 unsigned int expires = 0; 1192 unsigned int expires = 0;
1248 int ret; 1193 int ret;
1249 typeof(nf_nat_sip_expect_hook) nf_nat_sip_expect;
1250 1194
1251 /* Expected connections can not register again. */ 1195 /* Expected connections can not register again. */
1252 if (ct->status & IPS_EXPECTED) 1196 if (ct->status & IPS_EXPECTED)
@@ -1309,10 +1253,10 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff,
1309 exp->helper = nfct_help(ct)->helper; 1253 exp->helper = nfct_help(ct)->helper;
1310 exp->flags = NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE; 1254 exp->flags = NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE;
1311 1255
1312 nf_nat_sip_expect = rcu_dereference(nf_nat_sip_expect_hook); 1256 hooks = rcu_dereference(nf_nat_sip_hooks);
1313 if (nf_nat_sip_expect && ct->status & IPS_NAT_MASK) 1257 if (hooks && ct->status & IPS_NAT_MASK)
1314 ret = nf_nat_sip_expect(skb, protoff, dataoff, dptr, datalen, 1258 ret = hooks->expect(skb, protoff, dataoff, dptr, datalen,
1315 exp, matchoff, matchlen); 1259 exp, matchoff, matchlen);
1316 else { 1260 else {
1317 if (nf_ct_expect_related(exp) != 0) { 1261 if (nf_ct_expect_related(exp) != 0) {
1318 nf_ct_helper_log(skb, ct, "cannot add expectation"); 1262 nf_ct_helper_log(skb, ct, "cannot add expectation");
@@ -1515,7 +1459,7 @@ static int process_sip_msg(struct sk_buff *skb, struct nf_conn *ct,
1515 unsigned int protoff, unsigned int dataoff, 1459 unsigned int protoff, unsigned int dataoff,
1516 const char **dptr, unsigned int *datalen) 1460 const char **dptr, unsigned int *datalen)
1517{ 1461{
1518 typeof(nf_nat_sip_hook) nf_nat_sip; 1462 const struct nf_nat_sip_hooks *hooks;
1519 int ret; 1463 int ret;
1520 1464
1521 if (strnicmp(*dptr, "SIP/2.0 ", strlen("SIP/2.0 ")) != 0) 1465 if (strnicmp(*dptr, "SIP/2.0 ", strlen("SIP/2.0 ")) != 0)
@@ -1524,9 +1468,9 @@ static int process_sip_msg(struct sk_buff *skb, struct nf_conn *ct,
1524 ret = process_sip_response(skb, protoff, dataoff, dptr, datalen); 1468 ret = process_sip_response(skb, protoff, dataoff, dptr, datalen);
1525 1469
1526 if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) { 1470 if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) {
1527 nf_nat_sip = rcu_dereference(nf_nat_sip_hook); 1471 hooks = rcu_dereference(nf_nat_sip_hooks);
1528 if (nf_nat_sip && !nf_nat_sip(skb, protoff, dataoff, 1472 if (hooks && !hooks->msg(skb, protoff, dataoff,
1529 dptr, datalen)) { 1473 dptr, datalen)) {
1530 nf_ct_helper_log(skb, ct, "cannot NAT SIP message"); 1474 nf_ct_helper_log(skb, ct, "cannot NAT SIP message");
1531 ret = NF_DROP; 1475 ret = NF_DROP;
1532 } 1476 }
@@ -1546,7 +1490,6 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
1546 s16 diff, tdiff = 0; 1490 s16 diff, tdiff = 0;
1547 int ret = NF_ACCEPT; 1491 int ret = NF_ACCEPT;
1548 bool term; 1492 bool term;
1549 typeof(nf_nat_sip_seq_adjust_hook) nf_nat_sip_seq_adjust;
1550 1493
1551 if (ctinfo != IP_CT_ESTABLISHED && 1494 if (ctinfo != IP_CT_ESTABLISHED &&
1552 ctinfo != IP_CT_ESTABLISHED_REPLY) 1495 ctinfo != IP_CT_ESTABLISHED_REPLY)
@@ -1610,9 +1553,11 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
1610 } 1553 }
1611 1554
1612 if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) { 1555 if (ret == NF_ACCEPT && ct->status & IPS_NAT_MASK) {
1613 nf_nat_sip_seq_adjust = rcu_dereference(nf_nat_sip_seq_adjust_hook); 1556 const struct nf_nat_sip_hooks *hooks;
1614 if (nf_nat_sip_seq_adjust) 1557
1615 nf_nat_sip_seq_adjust(skb, protoff, tdiff); 1558 hooks = rcu_dereference(nf_nat_sip_hooks);
1559 if (hooks)
1560 hooks->seq_adjust(skb, protoff, tdiff);
1616 } 1561 }
1617 1562
1618 return ret; 1563 return ret;
diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c
index f9790405b7ff..b4d691db955e 100644
--- a/net/netfilter/nf_nat_sip.c
+++ b/net/netfilter/nf_nat_sip.c
@@ -625,33 +625,26 @@ static struct nf_ct_helper_expectfn sip_nat = {
625 625
626static void __exit nf_nat_sip_fini(void) 626static void __exit nf_nat_sip_fini(void)
627{ 627{
628 RCU_INIT_POINTER(nf_nat_sip_hook, NULL); 628 RCU_INIT_POINTER(nf_nat_sip_hooks, NULL);
629 RCU_INIT_POINTER(nf_nat_sip_seq_adjust_hook, NULL); 629
630 RCU_INIT_POINTER(nf_nat_sip_expect_hook, NULL);
631 RCU_INIT_POINTER(nf_nat_sdp_addr_hook, NULL);
632 RCU_INIT_POINTER(nf_nat_sdp_port_hook, NULL);
633 RCU_INIT_POINTER(nf_nat_sdp_session_hook, NULL);
634 RCU_INIT_POINTER(nf_nat_sdp_media_hook, NULL);
635 nf_ct_helper_expectfn_unregister(&sip_nat); 630 nf_ct_helper_expectfn_unregister(&sip_nat);
636 synchronize_rcu(); 631 synchronize_rcu();
637} 632}
638 633
634static const struct nf_nat_sip_hooks sip_hooks = {
635 .msg = nf_nat_sip,
636 .seq_adjust = nf_nat_sip_seq_adjust,
637 .expect = nf_nat_sip_expect,
638 .sdp_addr = nf_nat_sdp_addr,
639 .sdp_port = nf_nat_sdp_port,
640 .sdp_session = nf_nat_sdp_session,
641 .sdp_media = nf_nat_sdp_media,
642};
643
639static int __init nf_nat_sip_init(void) 644static int __init nf_nat_sip_init(void)
640{ 645{
641 BUG_ON(nf_nat_sip_hook != NULL); 646 BUG_ON(nf_nat_sip_hooks != NULL);
642 BUG_ON(nf_nat_sip_seq_adjust_hook != NULL); 647 RCU_INIT_POINTER(nf_nat_sip_hooks, &sip_hooks);
643 BUG_ON(nf_nat_sip_expect_hook != NULL);
644 BUG_ON(nf_nat_sdp_addr_hook != NULL);
645 BUG_ON(nf_nat_sdp_port_hook != NULL);
646 BUG_ON(nf_nat_sdp_session_hook != NULL);
647 BUG_ON(nf_nat_sdp_media_hook != NULL);
648 RCU_INIT_POINTER(nf_nat_sip_hook, nf_nat_sip);
649 RCU_INIT_POINTER(nf_nat_sip_seq_adjust_hook, nf_nat_sip_seq_adjust);
650 RCU_INIT_POINTER(nf_nat_sip_expect_hook, nf_nat_sip_expect);
651 RCU_INIT_POINTER(nf_nat_sdp_addr_hook, nf_nat_sdp_addr);
652 RCU_INIT_POINTER(nf_nat_sdp_port_hook, nf_nat_sdp_port);
653 RCU_INIT_POINTER(nf_nat_sdp_session_hook, nf_nat_sdp_session);
654 RCU_INIT_POINTER(nf_nat_sdp_media_hook, nf_nat_sdp_media);
655 nf_ct_helper_expectfn_register(&sip_nat); 648 nf_ct_helper_expectfn_register(&sip_nat);
656 return 0; 649 return 0;
657} 650}
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
index 50580494148d..476accd17145 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -49,10 +49,8 @@ static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = {
49}; 49};
50 50
51static int 51static int
52ctnl_timeout_parse_policy(struct ctnl_timeout *timeout, 52ctnl_timeout_parse_policy(void *timeouts, struct nf_conntrack_l4proto *l4proto,
53 struct nf_conntrack_l4proto *l4proto, 53 struct net *net, const struct nlattr *attr)
54 struct net *net,
55 const struct nlattr *attr)
56{ 54{
57 int ret = 0; 55 int ret = 0;
58 56
@@ -64,8 +62,7 @@ ctnl_timeout_parse_policy(struct ctnl_timeout *timeout,
64 if (ret < 0) 62 if (ret < 0)
65 return ret; 63 return ret;
66 64
67 ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net, 65 ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net, timeouts);
68 &timeout->data);
69 } 66 }
70 return ret; 67 return ret;
71} 68}
@@ -123,7 +120,8 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
123 goto err_proto_put; 120 goto err_proto_put;
124 } 121 }
125 122
126 ret = ctnl_timeout_parse_policy(matching, l4proto, net, 123 ret = ctnl_timeout_parse_policy(&matching->data,
124 l4proto, net,
127 cda[CTA_TIMEOUT_DATA]); 125 cda[CTA_TIMEOUT_DATA]);
128 return ret; 126 return ret;
129 } 127 }
@@ -138,7 +136,7 @@ cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb,
138 goto err_proto_put; 136 goto err_proto_put;
139 } 137 }
140 138
141 ret = ctnl_timeout_parse_policy(timeout, l4proto, net, 139 ret = ctnl_timeout_parse_policy(&timeout->data, l4proto, net,
142 cda[CTA_TIMEOUT_DATA]); 140 cda[CTA_TIMEOUT_DATA]);
143 if (ret < 0) 141 if (ret < 0)
144 goto err; 142 goto err;
@@ -342,6 +340,147 @@ cttimeout_del_timeout(struct sock *ctnl, struct sk_buff *skb,
342 return ret; 340 return ret;
343} 341}
344 342
343static int
344cttimeout_default_set(struct sock *ctnl, struct sk_buff *skb,
345 const struct nlmsghdr *nlh,
346 const struct nlattr * const cda[])
347{
348 __u16 l3num;
349 __u8 l4num;
350 struct nf_conntrack_l4proto *l4proto;
351 struct net *net = sock_net(skb->sk);
352 unsigned int *timeouts;
353 int ret;
354
355 if (!cda[CTA_TIMEOUT_L3PROTO] ||
356 !cda[CTA_TIMEOUT_L4PROTO] ||
357 !cda[CTA_TIMEOUT_DATA])
358 return -EINVAL;
359
360 l3num = ntohs(nla_get_be16(cda[CTA_TIMEOUT_L3PROTO]));
361 l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
362 l4proto = nf_ct_l4proto_find_get(l3num, l4num);
363
364 /* This protocol is not supported, skip. */
365 if (l4proto->l4proto != l4num) {
366 ret = -EOPNOTSUPP;
367 goto err;
368 }
369
370 timeouts = l4proto->get_timeouts(net);
371
372 ret = ctnl_timeout_parse_policy(timeouts, l4proto, net,
373 cda[CTA_TIMEOUT_DATA]);
374 if (ret < 0)
375 goto err;
376
377 nf_ct_l4proto_put(l4proto);
378 return 0;
379err:
380 nf_ct_l4proto_put(l4proto);
381 return ret;
382}
383
384static int
385cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
386 u32 seq, u32 type, int event,
387 struct nf_conntrack_l4proto *l4proto)
388{
389 struct nlmsghdr *nlh;
390 struct nfgenmsg *nfmsg;
391 unsigned int flags = portid ? NLM_F_MULTI : 0;
392
393 event |= NFNL_SUBSYS_CTNETLINK_TIMEOUT << 8;
394 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
395 if (nlh == NULL)
396 goto nlmsg_failure;
397
398 nfmsg = nlmsg_data(nlh);
399 nfmsg->nfgen_family = AF_UNSPEC;
400 nfmsg->version = NFNETLINK_V0;
401 nfmsg->res_id = 0;
402
403 if (nla_put_be16(skb, CTA_TIMEOUT_L3PROTO, htons(l4proto->l3proto)) ||
404 nla_put_u8(skb, CTA_TIMEOUT_L4PROTO, l4proto->l4proto))
405 goto nla_put_failure;
406
407 if (likely(l4proto->ctnl_timeout.obj_to_nlattr)) {
408 struct nlattr *nest_parms;
409 unsigned int *timeouts = l4proto->get_timeouts(net);
410 int ret;
411
412 nest_parms = nla_nest_start(skb,
413 CTA_TIMEOUT_DATA | NLA_F_NESTED);
414 if (!nest_parms)
415 goto nla_put_failure;
416
417 ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, timeouts);
418 if (ret < 0)
419 goto nla_put_failure;
420
421 nla_nest_end(skb, nest_parms);
422 }
423
424 nlmsg_end(skb, nlh);
425 return skb->len;
426
427nlmsg_failure:
428nla_put_failure:
429 nlmsg_cancel(skb, nlh);
430 return -1;
431}
432
433static int cttimeout_default_get(struct sock *ctnl, struct sk_buff *skb,
434 const struct nlmsghdr *nlh,
435 const struct nlattr * const cda[])
436{
437 __u16 l3num;
438 __u8 l4num;
439 struct nf_conntrack_l4proto *l4proto;
440 struct net *net = sock_net(skb->sk);
441 struct sk_buff *skb2;
442 int ret, err;
443
444 if (!cda[CTA_TIMEOUT_L3PROTO] || !cda[CTA_TIMEOUT_L4PROTO])
445 return -EINVAL;
446
447 l3num = ntohs(nla_get_be16(cda[CTA_TIMEOUT_L3PROTO]));
448 l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
449 l4proto = nf_ct_l4proto_find_get(l3num, l4num);
450
451 /* This protocol is not supported, skip. */
452 if (l4proto->l4proto != l4num) {
453 err = -EOPNOTSUPP;
454 goto err;
455 }
456
457 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
458 if (skb2 == NULL) {
459 err = -ENOMEM;
460 goto err;
461 }
462
463 ret = cttimeout_default_fill_info(net, skb2, NETLINK_CB(skb).portid,
464 nlh->nlmsg_seq,
465 NFNL_MSG_TYPE(nlh->nlmsg_type),
466 IPCTNL_MSG_TIMEOUT_DEFAULT_SET,
467 l4proto);
468 if (ret <= 0) {
469 kfree_skb(skb2);
470 err = -ENOMEM;
471 goto err;
472 }
473 ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
474 if (ret > 0)
475 ret = 0;
476
477 /* this avoids a loop in nfnetlink. */
478 return ret == -EAGAIN ? -ENOBUFS : ret;
479err:
480 nf_ct_l4proto_put(l4proto);
481 return err;
482}
483
345#ifdef CONFIG_NF_CONNTRACK_TIMEOUT 484#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
346static struct ctnl_timeout *ctnl_timeout_find_get(const char *name) 485static struct ctnl_timeout *ctnl_timeout_find_get(const char *name)
347{ 486{
@@ -384,6 +523,12 @@ static const struct nfnl_callback cttimeout_cb[IPCTNL_MSG_TIMEOUT_MAX] = {
384 [IPCTNL_MSG_TIMEOUT_DELETE] = { .call = cttimeout_del_timeout, 523 [IPCTNL_MSG_TIMEOUT_DELETE] = { .call = cttimeout_del_timeout,
385 .attr_count = CTA_TIMEOUT_MAX, 524 .attr_count = CTA_TIMEOUT_MAX,
386 .policy = cttimeout_nla_policy }, 525 .policy = cttimeout_nla_policy },
526 [IPCTNL_MSG_TIMEOUT_DEFAULT_SET]= { .call = cttimeout_default_set,
527 .attr_count = CTA_TIMEOUT_MAX,
528 .policy = cttimeout_nla_policy },
529 [IPCTNL_MSG_TIMEOUT_DEFAULT_GET]= { .call = cttimeout_default_get,
530 .attr_count = CTA_TIMEOUT_MAX,
531 .policy = cttimeout_nla_policy },
387}; 532};
388 533
389static const struct nfnetlink_subsystem cttimeout_subsys = { 534static const struct nfnetlink_subsystem cttimeout_subsys = {
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index d92cc317bf8b..3c4b69e5fe17 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -319,7 +319,8 @@ nfulnl_set_flags(struct nfulnl_instance *inst, u_int16_t flags)
319} 319}
320 320
321static struct sk_buff * 321static struct sk_buff *
322nfulnl_alloc_skb(u32 peer_portid, unsigned int inst_size, unsigned int pkt_size) 322nfulnl_alloc_skb(struct net *net, u32 peer_portid, unsigned int inst_size,
323 unsigned int pkt_size)
323{ 324{
324 struct sk_buff *skb; 325 struct sk_buff *skb;
325 unsigned int n; 326 unsigned int n;
@@ -328,13 +329,13 @@ nfulnl_alloc_skb(u32 peer_portid, unsigned int inst_size, unsigned int pkt_size)
328 * message. WARNING: has to be <= 128k due to slab restrictions */ 329 * message. WARNING: has to be <= 128k due to slab restrictions */
329 330
330 n = max(inst_size, pkt_size); 331 n = max(inst_size, pkt_size);
331 skb = nfnetlink_alloc_skb(&init_net, n, peer_portid, GFP_ATOMIC); 332 skb = nfnetlink_alloc_skb(net, n, peer_portid, GFP_ATOMIC);
332 if (!skb) { 333 if (!skb) {
333 if (n > pkt_size) { 334 if (n > pkt_size) {
334 /* try to allocate only as much as we need for current 335 /* try to allocate only as much as we need for current
335 * packet */ 336 * packet */
336 337
337 skb = nfnetlink_alloc_skb(&init_net, pkt_size, 338 skb = nfnetlink_alloc_skb(net, pkt_size,
338 peer_portid, GFP_ATOMIC); 339 peer_portid, GFP_ATOMIC);
339 if (!skb) 340 if (!skb)
340 pr_err("nfnetlink_log: can't even alloc %u bytes\n", 341 pr_err("nfnetlink_log: can't even alloc %u bytes\n",
@@ -702,8 +703,8 @@ nfulnl_log_packet(struct net *net,
702 } 703 }
703 704
704 if (!inst->skb) { 705 if (!inst->skb) {
705 inst->skb = nfulnl_alloc_skb(inst->peer_portid, inst->nlbufsiz, 706 inst->skb = nfulnl_alloc_skb(net, inst->peer_portid,
706 size); 707 inst->nlbufsiz, size);
707 if (!inst->skb) 708 if (!inst->skb)
708 goto alloc_failure; 709 goto alloc_failure;
709 } 710 }
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
index ae2e5c11d01a..21258cf70091 100644
--- a/net/netfilter/nfnetlink_queue_core.c
+++ b/net/netfilter/nfnetlink_queue_core.c
@@ -298,7 +298,7 @@ nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet,
298} 298}
299 299
300static struct sk_buff * 300static struct sk_buff *
301nfqnl_build_packet_message(struct nfqnl_instance *queue, 301nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
302 struct nf_queue_entry *entry, 302 struct nf_queue_entry *entry,
303 __be32 **packet_id_ptr) 303 __be32 **packet_id_ptr)
304{ 304{
@@ -372,7 +372,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
372 if (queue->flags & NFQA_CFG_F_CONNTRACK) 372 if (queue->flags & NFQA_CFG_F_CONNTRACK)
373 ct = nfqnl_ct_get(entskb, &size, &ctinfo); 373 ct = nfqnl_ct_get(entskb, &size, &ctinfo);
374 374
375 skb = nfnetlink_alloc_skb(&init_net, size, queue->peer_portid, 375 skb = nfnetlink_alloc_skb(net, size, queue->peer_portid,
376 GFP_ATOMIC); 376 GFP_ATOMIC);
377 if (!skb) 377 if (!skb)
378 return NULL; 378 return NULL;
@@ -525,7 +525,7 @@ __nfqnl_enqueue_packet(struct net *net, struct nfqnl_instance *queue,
525 __be32 *packet_id_ptr; 525 __be32 *packet_id_ptr;
526 int failopen = 0; 526 int failopen = 0;
527 527
528 nskb = nfqnl_build_packet_message(queue, entry, &packet_id_ptr); 528 nskb = nfqnl_build_packet_message(net, queue, entry, &packet_id_ptr);
529 if (nskb == NULL) { 529 if (nskb == NULL) {
530 err = -ENOMEM; 530 err = -ENOMEM;
531 goto err_out; 531 goto err_out;
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index cd24290f3b2f..e762de5ee89b 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -43,10 +43,42 @@ optlen(const u_int8_t *opt, unsigned int offset)
43 return opt[offset+1]; 43 return opt[offset+1];
44} 44}
45 45
46static u_int32_t tcpmss_reverse_mtu(struct net *net,
47 const struct sk_buff *skb,
48 unsigned int family)
49{
50 struct flowi fl;
51 const struct nf_afinfo *ai;
52 struct rtable *rt = NULL;
53 u_int32_t mtu = ~0U;
54
55 if (family == PF_INET) {
56 struct flowi4 *fl4 = &fl.u.ip4;
57 memset(fl4, 0, sizeof(*fl4));
58 fl4->daddr = ip_hdr(skb)->saddr;
59 } else {
60 struct flowi6 *fl6 = &fl.u.ip6;
61
62 memset(fl6, 0, sizeof(*fl6));
63 fl6->daddr = ipv6_hdr(skb)->saddr;
64 }
65 rcu_read_lock();
66 ai = nf_get_afinfo(family);
67 if (ai != NULL)
68 ai->route(net, (struct dst_entry **)&rt, &fl, false);
69 rcu_read_unlock();
70
71 if (rt != NULL) {
72 mtu = dst_mtu(&rt->dst);
73 dst_release(&rt->dst);
74 }
75 return mtu;
76}
77
46static int 78static int
47tcpmss_mangle_packet(struct sk_buff *skb, 79tcpmss_mangle_packet(struct sk_buff *skb,
48 const struct xt_action_param *par, 80 const struct xt_action_param *par,
49 unsigned int in_mtu, 81 unsigned int family,
50 unsigned int tcphoff, 82 unsigned int tcphoff,
51 unsigned int minlen) 83 unsigned int minlen)
52{ 84{
@@ -76,6 +108,9 @@ tcpmss_mangle_packet(struct sk_buff *skb,
76 return -1; 108 return -1;
77 109
78 if (info->mss == XT_TCPMSS_CLAMP_PMTU) { 110 if (info->mss == XT_TCPMSS_CLAMP_PMTU) {
111 struct net *net = dev_net(par->in ? par->in : par->out);
112 unsigned int in_mtu = tcpmss_reverse_mtu(net, skb, family);
113
79 if (dst_mtu(skb_dst(skb)) <= minlen) { 114 if (dst_mtu(skb_dst(skb)) <= minlen) {
80 net_err_ratelimited("unknown or invalid path-MTU (%u)\n", 115 net_err_ratelimited("unknown or invalid path-MTU (%u)\n",
81 dst_mtu(skb_dst(skb))); 116 dst_mtu(skb_dst(skb)));
@@ -165,37 +200,6 @@ tcpmss_mangle_packet(struct sk_buff *skb,
165 return TCPOLEN_MSS; 200 return TCPOLEN_MSS;
166} 201}
167 202
168static u_int32_t tcpmss_reverse_mtu(const struct sk_buff *skb,
169 unsigned int family)
170{
171 struct flowi fl;
172 const struct nf_afinfo *ai;
173 struct rtable *rt = NULL;
174 u_int32_t mtu = ~0U;
175
176 if (family == PF_INET) {
177 struct flowi4 *fl4 = &fl.u.ip4;
178 memset(fl4, 0, sizeof(*fl4));
179 fl4->daddr = ip_hdr(skb)->saddr;
180 } else {
181 struct flowi6 *fl6 = &fl.u.ip6;
182
183 memset(fl6, 0, sizeof(*fl6));
184 fl6->daddr = ipv6_hdr(skb)->saddr;
185 }
186 rcu_read_lock();
187 ai = nf_get_afinfo(family);
188 if (ai != NULL)
189 ai->route(&init_net, (struct dst_entry **)&rt, &fl, false);
190 rcu_read_unlock();
191
192 if (rt != NULL) {
193 mtu = dst_mtu(&rt->dst);
194 dst_release(&rt->dst);
195 }
196 return mtu;
197}
198
199static unsigned int 203static unsigned int
200tcpmss_tg4(struct sk_buff *skb, const struct xt_action_param *par) 204tcpmss_tg4(struct sk_buff *skb, const struct xt_action_param *par)
201{ 205{
@@ -204,7 +208,7 @@ tcpmss_tg4(struct sk_buff *skb, const struct xt_action_param *par)
204 int ret; 208 int ret;
205 209
206 ret = tcpmss_mangle_packet(skb, par, 210 ret = tcpmss_mangle_packet(skb, par,
207 tcpmss_reverse_mtu(skb, PF_INET), 211 PF_INET,
208 iph->ihl * 4, 212 iph->ihl * 4,
209 sizeof(*iph) + sizeof(struct tcphdr)); 213 sizeof(*iph) + sizeof(struct tcphdr));
210 if (ret < 0) 214 if (ret < 0)
@@ -233,7 +237,7 @@ tcpmss_tg6(struct sk_buff *skb, const struct xt_action_param *par)
233 if (tcphoff < 0) 237 if (tcphoff < 0)
234 return NF_DROP; 238 return NF_DROP;
235 ret = tcpmss_mangle_packet(skb, par, 239 ret = tcpmss_mangle_packet(skb, par,
236 tcpmss_reverse_mtu(skb, PF_INET6), 240 PF_INET6,
237 tcphoff, 241 tcphoff,
238 sizeof(*ipv6h) + sizeof(struct tcphdr)); 242 sizeof(*ipv6h) + sizeof(struct tcphdr));
239 if (ret < 0) 243 if (ret < 0)
diff --git a/net/netfilter/xt_set.c b/net/netfilter/xt_set.c
index 31790e789e22..e7c4e0e01ff5 100644
--- a/net/netfilter/xt_set.c
+++ b/net/netfilter/xt_set.c
@@ -81,7 +81,7 @@ set_match_v0_checkentry(const struct xt_mtchk_param *par)
81 struct xt_set_info_match_v0 *info = par->matchinfo; 81 struct xt_set_info_match_v0 *info = par->matchinfo;
82 ip_set_id_t index; 82 ip_set_id_t index;
83 83
84 index = ip_set_nfnl_get_byindex(info->match_set.index); 84 index = ip_set_nfnl_get_byindex(par->net, info->match_set.index);
85 85
86 if (index == IPSET_INVALID_ID) { 86 if (index == IPSET_INVALID_ID) {
87 pr_warning("Cannot find set indentified by id %u to match\n", 87 pr_warning("Cannot find set indentified by id %u to match\n",
@@ -91,7 +91,7 @@ set_match_v0_checkentry(const struct xt_mtchk_param *par)
91 if (info->match_set.u.flags[IPSET_DIM_MAX-1] != 0) { 91 if (info->match_set.u.flags[IPSET_DIM_MAX-1] != 0) {
92 pr_warning("Protocol error: set match dimension " 92 pr_warning("Protocol error: set match dimension "
93 "is over the limit!\n"); 93 "is over the limit!\n");
94 ip_set_nfnl_put(info->match_set.index); 94 ip_set_nfnl_put(par->net, info->match_set.index);
95 return -ERANGE; 95 return -ERANGE;
96 } 96 }
97 97
@@ -106,9 +106,104 @@ set_match_v0_destroy(const struct xt_mtdtor_param *par)
106{ 106{
107 struct xt_set_info_match_v0 *info = par->matchinfo; 107 struct xt_set_info_match_v0 *info = par->matchinfo;
108 108
109 ip_set_nfnl_put(info->match_set.index); 109 ip_set_nfnl_put(par->net, info->match_set.index);
110} 110}
111 111
112/* Revision 1 match */
113
114static bool
115set_match_v1(const struct sk_buff *skb, struct xt_action_param *par)
116{
117 const struct xt_set_info_match_v1 *info = par->matchinfo;
118 ADT_OPT(opt, par->family, info->match_set.dim,
119 info->match_set.flags, 0, UINT_MAX);
120
121 if (opt.flags & IPSET_RETURN_NOMATCH)
122 opt.cmdflags |= IPSET_FLAG_RETURN_NOMATCH;
123
124 return match_set(info->match_set.index, skb, par, &opt,
125 info->match_set.flags & IPSET_INV_MATCH);
126}
127
128static int
129set_match_v1_checkentry(const struct xt_mtchk_param *par)
130{
131 struct xt_set_info_match_v1 *info = par->matchinfo;
132 ip_set_id_t index;
133
134 index = ip_set_nfnl_get_byindex(par->net, info->match_set.index);
135
136 if (index == IPSET_INVALID_ID) {
137 pr_warning("Cannot find set indentified by id %u to match\n",
138 info->match_set.index);
139 return -ENOENT;
140 }
141 if (info->match_set.dim > IPSET_DIM_MAX) {
142 pr_warning("Protocol error: set match dimension "
143 "is over the limit!\n");
144 ip_set_nfnl_put(par->net, info->match_set.index);
145 return -ERANGE;
146 }
147
148 return 0;
149}
150
151static void
152set_match_v1_destroy(const struct xt_mtdtor_param *par)
153{
154 struct xt_set_info_match_v1 *info = par->matchinfo;
155
156 ip_set_nfnl_put(par->net, info->match_set.index);
157}
158
159/* Revision 3 match */
160
161static bool
162match_counter(u64 counter, const struct ip_set_counter_match *info)
163{
164 switch (info->op) {
165 case IPSET_COUNTER_NONE:
166 return true;
167 case IPSET_COUNTER_EQ:
168 return counter == info->value;
169 case IPSET_COUNTER_NE:
170 return counter != info->value;
171 case IPSET_COUNTER_LT:
172 return counter < info->value;
173 case IPSET_COUNTER_GT:
174 return counter > info->value;
175 }
176 return false;
177}
178
179static bool
180set_match_v3(const struct sk_buff *skb, struct xt_action_param *par)
181{
182 const struct xt_set_info_match_v3 *info = par->matchinfo;
183 ADT_OPT(opt, par->family, info->match_set.dim,
184 info->match_set.flags, info->flags, UINT_MAX);
185 int ret;
186
187 if (info->packets.op != IPSET_COUNTER_NONE ||
188 info->bytes.op != IPSET_COUNTER_NONE)
189 opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS;
190
191 ret = match_set(info->match_set.index, skb, par, &opt,
192 info->match_set.flags & IPSET_INV_MATCH);
193
194 if (!(ret && opt.cmdflags & IPSET_FLAG_MATCH_COUNTERS))
195 return ret;
196
197 if (!match_counter(opt.ext.packets, &info->packets))
198 return 0;
199 return match_counter(opt.ext.bytes, &info->bytes);
200}
201
202#define set_match_v3_checkentry set_match_v1_checkentry
203#define set_match_v3_destroy set_match_v1_destroy
204
205/* Revision 0 interface: backward compatible with netfilter/iptables */
206
112static unsigned int 207static unsigned int
113set_target_v0(struct sk_buff *skb, const struct xt_action_param *par) 208set_target_v0(struct sk_buff *skb, const struct xt_action_param *par)
114{ 209{
@@ -133,7 +228,7 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par)
133 ip_set_id_t index; 228 ip_set_id_t index;
134 229
135 if (info->add_set.index != IPSET_INVALID_ID) { 230 if (info->add_set.index != IPSET_INVALID_ID) {
136 index = ip_set_nfnl_get_byindex(info->add_set.index); 231 index = ip_set_nfnl_get_byindex(par->net, info->add_set.index);
137 if (index == IPSET_INVALID_ID) { 232 if (index == IPSET_INVALID_ID) {
138 pr_warning("Cannot find add_set index %u as target\n", 233 pr_warning("Cannot find add_set index %u as target\n",
139 info->add_set.index); 234 info->add_set.index);
@@ -142,12 +237,12 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par)
142 } 237 }
143 238
144 if (info->del_set.index != IPSET_INVALID_ID) { 239 if (info->del_set.index != IPSET_INVALID_ID) {
145 index = ip_set_nfnl_get_byindex(info->del_set.index); 240 index = ip_set_nfnl_get_byindex(par->net, info->del_set.index);
146 if (index == IPSET_INVALID_ID) { 241 if (index == IPSET_INVALID_ID) {
147 pr_warning("Cannot find del_set index %u as target\n", 242 pr_warning("Cannot find del_set index %u as target\n",
148 info->del_set.index); 243 info->del_set.index);
149 if (info->add_set.index != IPSET_INVALID_ID) 244 if (info->add_set.index != IPSET_INVALID_ID)
150 ip_set_nfnl_put(info->add_set.index); 245 ip_set_nfnl_put(par->net, info->add_set.index);
151 return -ENOENT; 246 return -ENOENT;
152 } 247 }
153 } 248 }
@@ -156,9 +251,9 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par)
156 pr_warning("Protocol error: SET target dimension " 251 pr_warning("Protocol error: SET target dimension "
157 "is over the limit!\n"); 252 "is over the limit!\n");
158 if (info->add_set.index != IPSET_INVALID_ID) 253 if (info->add_set.index != IPSET_INVALID_ID)
159 ip_set_nfnl_put(info->add_set.index); 254 ip_set_nfnl_put(par->net, info->add_set.index);
160 if (info->del_set.index != IPSET_INVALID_ID) 255 if (info->del_set.index != IPSET_INVALID_ID)
161 ip_set_nfnl_put(info->del_set.index); 256 ip_set_nfnl_put(par->net, info->del_set.index);
162 return -ERANGE; 257 return -ERANGE;
163 } 258 }
164 259
@@ -175,57 +270,12 @@ set_target_v0_destroy(const struct xt_tgdtor_param *par)
175 const struct xt_set_info_target_v0 *info = par->targinfo; 270 const struct xt_set_info_target_v0 *info = par->targinfo;
176 271
177 if (info->add_set.index != IPSET_INVALID_ID) 272 if (info->add_set.index != IPSET_INVALID_ID)
178 ip_set_nfnl_put(info->add_set.index); 273 ip_set_nfnl_put(par->net, info->add_set.index);
179 if (info->del_set.index != IPSET_INVALID_ID) 274 if (info->del_set.index != IPSET_INVALID_ID)
180 ip_set_nfnl_put(info->del_set.index); 275 ip_set_nfnl_put(par->net, info->del_set.index);
181} 276}
182 277
183/* Revision 1 match and target */ 278/* Revision 1 target */
184
185static bool
186set_match_v1(const struct sk_buff *skb, struct xt_action_param *par)
187{
188 const struct xt_set_info_match_v1 *info = par->matchinfo;
189 ADT_OPT(opt, par->family, info->match_set.dim,
190 info->match_set.flags, 0, UINT_MAX);
191
192 if (opt.flags & IPSET_RETURN_NOMATCH)
193 opt.cmdflags |= IPSET_FLAG_RETURN_NOMATCH;
194
195 return match_set(info->match_set.index, skb, par, &opt,
196 info->match_set.flags & IPSET_INV_MATCH);
197}
198
199static int
200set_match_v1_checkentry(const struct xt_mtchk_param *par)
201{
202 struct xt_set_info_match_v1 *info = par->matchinfo;
203 ip_set_id_t index;
204
205 index = ip_set_nfnl_get_byindex(info->match_set.index);
206
207 if (index == IPSET_INVALID_ID) {
208 pr_warning("Cannot find set indentified by id %u to match\n",
209 info->match_set.index);
210 return -ENOENT;
211 }
212 if (info->match_set.dim > IPSET_DIM_MAX) {
213 pr_warning("Protocol error: set match dimension "
214 "is over the limit!\n");
215 ip_set_nfnl_put(info->match_set.index);
216 return -ERANGE;
217 }
218
219 return 0;
220}
221
222static void
223set_match_v1_destroy(const struct xt_mtdtor_param *par)
224{
225 struct xt_set_info_match_v1 *info = par->matchinfo;
226
227 ip_set_nfnl_put(info->match_set.index);
228}
229 279
230static unsigned int 280static unsigned int
231set_target_v1(struct sk_buff *skb, const struct xt_action_param *par) 281set_target_v1(struct sk_buff *skb, const struct xt_action_param *par)
@@ -251,7 +301,7 @@ set_target_v1_checkentry(const struct xt_tgchk_param *par)
251 ip_set_id_t index; 301 ip_set_id_t index;
252 302
253 if (info->add_set.index != IPSET_INVALID_ID) { 303 if (info->add_set.index != IPSET_INVALID_ID) {
254 index = ip_set_nfnl_get_byindex(info->add_set.index); 304 index = ip_set_nfnl_get_byindex(par->net, info->add_set.index);
255 if (index == IPSET_INVALID_ID) { 305 if (index == IPSET_INVALID_ID) {
256 pr_warning("Cannot find add_set index %u as target\n", 306 pr_warning("Cannot find add_set index %u as target\n",
257 info->add_set.index); 307 info->add_set.index);
@@ -260,12 +310,12 @@ set_target_v1_checkentry(const struct xt_tgchk_param *par)
260 } 310 }
261 311
262 if (info->del_set.index != IPSET_INVALID_ID) { 312 if (info->del_set.index != IPSET_INVALID_ID) {
263 index = ip_set_nfnl_get_byindex(info->del_set.index); 313 index = ip_set_nfnl_get_byindex(par->net, info->del_set.index);
264 if (index == IPSET_INVALID_ID) { 314 if (index == IPSET_INVALID_ID) {
265 pr_warning("Cannot find del_set index %u as target\n", 315 pr_warning("Cannot find del_set index %u as target\n",
266 info->del_set.index); 316 info->del_set.index);
267 if (info->add_set.index != IPSET_INVALID_ID) 317 if (info->add_set.index != IPSET_INVALID_ID)
268 ip_set_nfnl_put(info->add_set.index); 318 ip_set_nfnl_put(par->net, info->add_set.index);
269 return -ENOENT; 319 return -ENOENT;
270 } 320 }
271 } 321 }
@@ -274,9 +324,9 @@ set_target_v1_checkentry(const struct xt_tgchk_param *par)
274 pr_warning("Protocol error: SET target dimension " 324 pr_warning("Protocol error: SET target dimension "
275 "is over the limit!\n"); 325 "is over the limit!\n");
276 if (info->add_set.index != IPSET_INVALID_ID) 326 if (info->add_set.index != IPSET_INVALID_ID)
277 ip_set_nfnl_put(info->add_set.index); 327 ip_set_nfnl_put(par->net, info->add_set.index);
278 if (info->del_set.index != IPSET_INVALID_ID) 328 if (info->del_set.index != IPSET_INVALID_ID)
279 ip_set_nfnl_put(info->del_set.index); 329 ip_set_nfnl_put(par->net, info->del_set.index);
280 return -ERANGE; 330 return -ERANGE;
281 } 331 }
282 332
@@ -289,9 +339,9 @@ set_target_v1_destroy(const struct xt_tgdtor_param *par)
289 const struct xt_set_info_target_v1 *info = par->targinfo; 339 const struct xt_set_info_target_v1 *info = par->targinfo;
290 340
291 if (info->add_set.index != IPSET_INVALID_ID) 341 if (info->add_set.index != IPSET_INVALID_ID)
292 ip_set_nfnl_put(info->add_set.index); 342 ip_set_nfnl_put(par->net, info->add_set.index);
293 if (info->del_set.index != IPSET_INVALID_ID) 343 if (info->del_set.index != IPSET_INVALID_ID)
294 ip_set_nfnl_put(info->del_set.index); 344 ip_set_nfnl_put(par->net, info->del_set.index);
295} 345}
296 346
297/* Revision 2 target */ 347/* Revision 2 target */
@@ -320,52 +370,6 @@ set_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
320#define set_target_v2_checkentry set_target_v1_checkentry 370#define set_target_v2_checkentry set_target_v1_checkentry
321#define set_target_v2_destroy set_target_v1_destroy 371#define set_target_v2_destroy set_target_v1_destroy
322 372
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
369static struct xt_match set_matches[] __read_mostly = { 373static struct xt_match set_matches[] __read_mostly = {
370 { 374 {
371 .name = "set", 375 .name = "set",
diff --git a/net/sched/em_ipset.c b/net/sched/em_ipset.c
index 938b7cbf5627..1ac41d3de5c3 100644
--- a/net/sched/em_ipset.c
+++ b/net/sched/em_ipset.c
@@ -24,11 +24,12 @@ static int em_ipset_change(struct tcf_proto *tp, void *data, int data_len,
24{ 24{
25 struct xt_set_info *set = data; 25 struct xt_set_info *set = data;
26 ip_set_id_t index; 26 ip_set_id_t index;
27 struct net *net = qdisc_dev(tp->q)->nd_net;
27 28
28 if (data_len != sizeof(*set)) 29 if (data_len != sizeof(*set))
29 return -EINVAL; 30 return -EINVAL;
30 31
31 index = ip_set_nfnl_get_byindex(set->index); 32 index = ip_set_nfnl_get_byindex(net, set->index);
32 if (index == IPSET_INVALID_ID) 33 if (index == IPSET_INVALID_ID)
33 return -ENOENT; 34 return -ENOENT;
34 35
@@ -37,7 +38,7 @@ static int em_ipset_change(struct tcf_proto *tp, void *data, int data_len,
37 if (em->data) 38 if (em->data)
38 return 0; 39 return 0;
39 40
40 ip_set_nfnl_put(index); 41 ip_set_nfnl_put(net, index);
41 return -ENOMEM; 42 return -ENOMEM;
42} 43}
43 44
@@ -45,7 +46,7 @@ static void em_ipset_destroy(struct tcf_proto *p, struct tcf_ematch *em)
45{ 46{
46 const struct xt_set_info *set = (const void *) em->data; 47 const struct xt_set_info *set = (const void *) em->data;
47 if (set) { 48 if (set) {
48 ip_set_nfnl_put(set->index); 49 ip_set_nfnl_put(qdisc_dev(p->q)->nd_net, set->index);
49 kfree((void *) em->data); 50 kfree((void *) em->data);
50 } 51 }
51} 52}