diff options
author | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2011-03-20 10:33:26 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2011-03-20 10:33:26 -0400 |
commit | 5e0c1eb7e6b61998c7ecd39b7f69a15773d894d4 (patch) | |
tree | 4fba9a1410925d0a6d7a8a39aa8cc447e6f9251c | |
parent | b26fa4e0275426450238a14158bc1db24bb696e6 (diff) |
netfilter: ipset: fix address ranges at hash:*port* types
The hash:*port* types with IPv4 silently ignored when address ranges
with non TCP/UDP were added/deleted from the set and used the first
address from the range only.
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r-- | include/linux/netfilter/ipset/ip_set_getport.h | 10 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_hash_ipport.c | 34 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_hash_ipportip.c | 34 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_hash_ipportnet.c | 34 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_hash_netport.c | 30 |
5 files changed, 48 insertions, 94 deletions
diff --git a/include/linux/netfilter/ipset/ip_set_getport.h b/include/linux/netfilter/ipset/ip_set_getport.h index 3882a81a3b3c..5aebd170f899 100644 --- a/include/linux/netfilter/ipset/ip_set_getport.h +++ b/include/linux/netfilter/ipset/ip_set_getport.h | |||
@@ -18,4 +18,14 @@ static inline bool ip_set_get_ip6_port(const struct sk_buff *skb, bool src, | |||
18 | extern bool ip_set_get_ip_port(const struct sk_buff *skb, u8 pf, bool src, | 18 | extern bool ip_set_get_ip_port(const struct sk_buff *skb, u8 pf, bool src, |
19 | __be16 *port); | 19 | __be16 *port); |
20 | 20 | ||
21 | static inline bool ip_set_proto_with_ports(u8 proto) | ||
22 | { | ||
23 | switch (proto) { | ||
24 | case IPPROTO_TCP: | ||
25 | case IPPROTO_UDP: | ||
26 | return true; | ||
27 | } | ||
28 | return false; | ||
29 | } | ||
30 | |||
21 | #endif /*_IP_SET_GETPORT_H*/ | 31 | #endif /*_IP_SET_GETPORT_H*/ |
diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c index adbe787ea5dc..b9214145d357 100644 --- a/net/netfilter/ipset/ip_set_hash_ipport.c +++ b/net/netfilter/ipset/ip_set_hash_ipport.c | |||
@@ -150,6 +150,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
150 | struct hash_ipport4_elem data = { }; | 150 | struct hash_ipport4_elem data = { }; |
151 | u32 ip, ip_to, p, port, port_to; | 151 | u32 ip, ip_to, p, port, port_to; |
152 | u32 timeout = h->timeout; | 152 | u32 timeout = h->timeout; |
153 | bool with_ports = false; | ||
153 | int ret; | 154 | int ret; |
154 | 155 | ||
155 | if (unlikely(!tb[IPSET_ATTR_IP] || | 156 | if (unlikely(!tb[IPSET_ATTR_IP] || |
@@ -172,21 +173,15 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
172 | 173 | ||
173 | if (tb[IPSET_ATTR_PROTO]) { | 174 | if (tb[IPSET_ATTR_PROTO]) { |
174 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); | 175 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); |
176 | with_ports = ip_set_proto_with_ports(data.proto); | ||
175 | 177 | ||
176 | if (data.proto == 0) | 178 | if (data.proto == 0) |
177 | return -IPSET_ERR_INVALID_PROTO; | 179 | return -IPSET_ERR_INVALID_PROTO; |
178 | } else | 180 | } else |
179 | return -IPSET_ERR_MISSING_PROTO; | 181 | return -IPSET_ERR_MISSING_PROTO; |
180 | 182 | ||
181 | switch (data.proto) { | 183 | if (!(with_ports || data.proto == IPPROTO_ICMP)) |
182 | case IPPROTO_UDP: | ||
183 | case IPPROTO_TCP: | ||
184 | case IPPROTO_ICMP: | ||
185 | break; | ||
186 | default: | ||
187 | data.port = 0; | 184 | data.port = 0; |
188 | break; | ||
189 | } | ||
190 | 185 | ||
191 | if (tb[IPSET_ATTR_TIMEOUT]) { | 186 | if (tb[IPSET_ATTR_TIMEOUT]) { |
192 | if (!with_timeout(h->timeout)) | 187 | if (!with_timeout(h->timeout)) |
@@ -195,7 +190,6 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
195 | } | 190 | } |
196 | 191 | ||
197 | if (adt == IPSET_TEST || | 192 | if (adt == IPSET_TEST || |
198 | !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || | ||
199 | !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || | 193 | !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || |
200 | tb[IPSET_ATTR_PORT_TO])) { | 194 | tb[IPSET_ATTR_PORT_TO])) { |
201 | ret = adtfn(set, &data, timeout); | 195 | ret = adtfn(set, &data, timeout); |
@@ -219,13 +213,12 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
219 | } else | 213 | } else |
220 | ip_to = ip; | 214 | ip_to = ip; |
221 | 215 | ||
222 | port = ntohs(data.port); | 216 | port_to = port = ntohs(data.port); |
223 | if (tb[IPSET_ATTR_PORT_TO]) { | 217 | if (with_ports && tb[IPSET_ATTR_PORT_TO]) { |
224 | port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); | 218 | port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); |
225 | if (port > port_to) | 219 | if (port > port_to) |
226 | swap(port, port_to); | 220 | swap(port, port_to); |
227 | } else | 221 | } |
228 | port_to = port; | ||
229 | 222 | ||
230 | for (; !before(ip_to, ip); ip++) | 223 | for (; !before(ip_to, ip); ip++) |
231 | for (p = port; p <= port_to; p++) { | 224 | for (p = port; p <= port_to; p++) { |
@@ -361,6 +354,7 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
361 | struct hash_ipport6_elem data = { }; | 354 | struct hash_ipport6_elem data = { }; |
362 | u32 port, port_to; | 355 | u32 port, port_to; |
363 | u32 timeout = h->timeout; | 356 | u32 timeout = h->timeout; |
357 | bool with_ports = false; | ||
364 | int ret; | 358 | int ret; |
365 | 359 | ||
366 | if (unlikely(!tb[IPSET_ATTR_IP] || | 360 | if (unlikely(!tb[IPSET_ATTR_IP] || |
@@ -385,21 +379,15 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
385 | 379 | ||
386 | if (tb[IPSET_ATTR_PROTO]) { | 380 | if (tb[IPSET_ATTR_PROTO]) { |
387 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); | 381 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); |
382 | with_ports = ip_set_proto_with_ports(data.proto); | ||
388 | 383 | ||
389 | if (data.proto == 0) | 384 | if (data.proto == 0) |
390 | return -IPSET_ERR_INVALID_PROTO; | 385 | return -IPSET_ERR_INVALID_PROTO; |
391 | } else | 386 | } else |
392 | return -IPSET_ERR_MISSING_PROTO; | 387 | return -IPSET_ERR_MISSING_PROTO; |
393 | 388 | ||
394 | switch (data.proto) { | 389 | if (!(with_ports || data.proto == IPPROTO_ICMPV6)) |
395 | case IPPROTO_UDP: | ||
396 | case IPPROTO_TCP: | ||
397 | case IPPROTO_ICMPV6: | ||
398 | break; | ||
399 | default: | ||
400 | data.port = 0; | 390 | data.port = 0; |
401 | break; | ||
402 | } | ||
403 | 391 | ||
404 | if (tb[IPSET_ATTR_TIMEOUT]) { | 392 | if (tb[IPSET_ATTR_TIMEOUT]) { |
405 | if (!with_timeout(h->timeout)) | 393 | if (!with_timeout(h->timeout)) |
@@ -407,9 +395,7 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
407 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); | 395 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); |
408 | } | 396 | } |
409 | 397 | ||
410 | if (adt == IPSET_TEST || | 398 | if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { |
411 | !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || | ||
412 | !tb[IPSET_ATTR_PORT_TO]) { | ||
413 | ret = adtfn(set, &data, timeout); | 399 | ret = adtfn(set, &data, timeout); |
414 | return ip_set_eexist(ret, flags) ? 0 : ret; | 400 | return ip_set_eexist(ret, flags) ? 0 : ret; |
415 | } | 401 | } |
diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c index 22e23abb86c6..4642872df6e1 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportip.c +++ b/net/netfilter/ipset/ip_set_hash_ipportip.c | |||
@@ -154,6 +154,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
154 | struct hash_ipportip4_elem data = { }; | 154 | struct hash_ipportip4_elem data = { }; |
155 | u32 ip, ip_to, p, port, port_to; | 155 | u32 ip, ip_to, p, port, port_to; |
156 | u32 timeout = h->timeout; | 156 | u32 timeout = h->timeout; |
157 | bool with_ports = false; | ||
157 | int ret; | 158 | int ret; |
158 | 159 | ||
159 | if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || | 160 | if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || |
@@ -180,21 +181,15 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
180 | 181 | ||
181 | if (tb[IPSET_ATTR_PROTO]) { | 182 | if (tb[IPSET_ATTR_PROTO]) { |
182 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); | 183 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); |
184 | with_ports = ip_set_proto_with_ports(data.proto); | ||
183 | 185 | ||
184 | if (data.proto == 0) | 186 | if (data.proto == 0) |
185 | return -IPSET_ERR_INVALID_PROTO; | 187 | return -IPSET_ERR_INVALID_PROTO; |
186 | } else | 188 | } else |
187 | return -IPSET_ERR_MISSING_PROTO; | 189 | return -IPSET_ERR_MISSING_PROTO; |
188 | 190 | ||
189 | switch (data.proto) { | 191 | if (!(with_ports || data.proto == IPPROTO_ICMP)) |
190 | case IPPROTO_UDP: | ||
191 | case IPPROTO_TCP: | ||
192 | case IPPROTO_ICMP: | ||
193 | break; | ||
194 | default: | ||
195 | data.port = 0; | 192 | data.port = 0; |
196 | break; | ||
197 | } | ||
198 | 193 | ||
199 | if (tb[IPSET_ATTR_TIMEOUT]) { | 194 | if (tb[IPSET_ATTR_TIMEOUT]) { |
200 | if (!with_timeout(h->timeout)) | 195 | if (!with_timeout(h->timeout)) |
@@ -203,7 +198,6 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
203 | } | 198 | } |
204 | 199 | ||
205 | if (adt == IPSET_TEST || | 200 | if (adt == IPSET_TEST || |
206 | !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || | ||
207 | !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || | 201 | !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || |
208 | tb[IPSET_ATTR_PORT_TO])) { | 202 | tb[IPSET_ATTR_PORT_TO])) { |
209 | ret = adtfn(set, &data, timeout); | 203 | ret = adtfn(set, &data, timeout); |
@@ -227,13 +221,12 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
227 | } else | 221 | } else |
228 | ip_to = ip; | 222 | ip_to = ip; |
229 | 223 | ||
230 | port = ntohs(data.port); | 224 | port_to = port = ntohs(data.port); |
231 | if (tb[IPSET_ATTR_PORT_TO]) { | 225 | if (with_ports && tb[IPSET_ATTR_PORT_TO]) { |
232 | port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); | 226 | port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); |
233 | if (port > port_to) | 227 | if (port > port_to) |
234 | swap(port, port_to); | 228 | swap(port, port_to); |
235 | } else | 229 | } |
236 | port_to = port; | ||
237 | 230 | ||
238 | for (; !before(ip_to, ip); ip++) | 231 | for (; !before(ip_to, ip); ip++) |
239 | for (p = port; p <= port_to; p++) { | 232 | for (p = port; p <= port_to; p++) { |
@@ -375,6 +368,7 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
375 | struct hash_ipportip6_elem data = { }; | 368 | struct hash_ipportip6_elem data = { }; |
376 | u32 port, port_to; | 369 | u32 port, port_to; |
377 | u32 timeout = h->timeout; | 370 | u32 timeout = h->timeout; |
371 | bool with_ports = false; | ||
378 | int ret; | 372 | int ret; |
379 | 373 | ||
380 | if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || | 374 | if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || |
@@ -403,21 +397,15 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
403 | 397 | ||
404 | if (tb[IPSET_ATTR_PROTO]) { | 398 | if (tb[IPSET_ATTR_PROTO]) { |
405 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); | 399 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); |
400 | with_ports = ip_set_proto_with_ports(data.proto); | ||
406 | 401 | ||
407 | if (data.proto == 0) | 402 | if (data.proto == 0) |
408 | return -IPSET_ERR_INVALID_PROTO; | 403 | return -IPSET_ERR_INVALID_PROTO; |
409 | } else | 404 | } else |
410 | return -IPSET_ERR_MISSING_PROTO; | 405 | return -IPSET_ERR_MISSING_PROTO; |
411 | 406 | ||
412 | switch (data.proto) { | 407 | if (!(with_ports || data.proto == IPPROTO_ICMPV6)) |
413 | case IPPROTO_UDP: | ||
414 | case IPPROTO_TCP: | ||
415 | case IPPROTO_ICMPV6: | ||
416 | break; | ||
417 | default: | ||
418 | data.port = 0; | 408 | data.port = 0; |
419 | break; | ||
420 | } | ||
421 | 409 | ||
422 | if (tb[IPSET_ATTR_TIMEOUT]) { | 410 | if (tb[IPSET_ATTR_TIMEOUT]) { |
423 | if (!with_timeout(h->timeout)) | 411 | if (!with_timeout(h->timeout)) |
@@ -425,9 +413,7 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
425 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); | 413 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); |
426 | } | 414 | } |
427 | 415 | ||
428 | if (adt == IPSET_TEST || | 416 | if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { |
429 | !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || | ||
430 | !tb[IPSET_ATTR_PORT_TO]) { | ||
431 | ret = adtfn(set, &data, timeout); | 417 | ret = adtfn(set, &data, timeout); |
432 | return ip_set_eexist(ret, flags) ? 0 : ret; | 418 | return ip_set_eexist(ret, flags) ? 0 : ret; |
433 | } | 419 | } |
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index 6033e8b54bbd..2cb84a54b7ad 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c | |||
@@ -174,6 +174,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
174 | struct hash_ipportnet4_elem data = { .cidr = HOST_MASK }; | 174 | struct hash_ipportnet4_elem data = { .cidr = HOST_MASK }; |
175 | u32 ip, ip_to, p, port, port_to; | 175 | u32 ip, ip_to, p, port, port_to; |
176 | u32 timeout = h->timeout; | 176 | u32 timeout = h->timeout; |
177 | bool with_ports = false; | ||
177 | int ret; | 178 | int ret; |
178 | 179 | ||
179 | if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || | 180 | if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || |
@@ -208,21 +209,15 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
208 | 209 | ||
209 | if (tb[IPSET_ATTR_PROTO]) { | 210 | if (tb[IPSET_ATTR_PROTO]) { |
210 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); | 211 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); |
212 | with_ports = ip_set_proto_with_ports(data.proto); | ||
211 | 213 | ||
212 | if (data.proto == 0) | 214 | if (data.proto == 0) |
213 | return -IPSET_ERR_INVALID_PROTO; | 215 | return -IPSET_ERR_INVALID_PROTO; |
214 | } else | 216 | } else |
215 | return -IPSET_ERR_MISSING_PROTO; | 217 | return -IPSET_ERR_MISSING_PROTO; |
216 | 218 | ||
217 | switch (data.proto) { | 219 | if (!(with_ports || data.proto == IPPROTO_ICMP)) |
218 | case IPPROTO_UDP: | ||
219 | case IPPROTO_TCP: | ||
220 | case IPPROTO_ICMP: | ||
221 | break; | ||
222 | default: | ||
223 | data.port = 0; | 220 | data.port = 0; |
224 | break; | ||
225 | } | ||
226 | 221 | ||
227 | if (tb[IPSET_ATTR_TIMEOUT]) { | 222 | if (tb[IPSET_ATTR_TIMEOUT]) { |
228 | if (!with_timeout(h->timeout)) | 223 | if (!with_timeout(h->timeout)) |
@@ -231,7 +226,6 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
231 | } | 226 | } |
232 | 227 | ||
233 | if (adt == IPSET_TEST || | 228 | if (adt == IPSET_TEST || |
234 | !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || | ||
235 | !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || | 229 | !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || |
236 | tb[IPSET_ATTR_PORT_TO])) { | 230 | tb[IPSET_ATTR_PORT_TO])) { |
237 | ret = adtfn(set, &data, timeout); | 231 | ret = adtfn(set, &data, timeout); |
@@ -255,13 +249,12 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
255 | } else | 249 | } else |
256 | ip_to = ip; | 250 | ip_to = ip; |
257 | 251 | ||
258 | port = ntohs(data.port); | 252 | port_to = port = ntohs(data.port); |
259 | if (tb[IPSET_ATTR_PORT_TO]) { | 253 | if (with_ports && tb[IPSET_ATTR_PORT_TO]) { |
260 | port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); | 254 | port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); |
261 | if (port > port_to) | 255 | if (port > port_to) |
262 | swap(port, port_to); | 256 | swap(port, port_to); |
263 | } else | 257 | } |
264 | port_to = port; | ||
265 | 258 | ||
266 | for (; !before(ip_to, ip); ip++) | 259 | for (; !before(ip_to, ip); ip++) |
267 | for (p = port; p <= port_to; p++) { | 260 | for (p = port; p <= port_to; p++) { |
@@ -429,6 +422,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
429 | struct hash_ipportnet6_elem data = { .cidr = HOST_MASK }; | 422 | struct hash_ipportnet6_elem data = { .cidr = HOST_MASK }; |
430 | u32 port, port_to; | 423 | u32 port, port_to; |
431 | u32 timeout = h->timeout; | 424 | u32 timeout = h->timeout; |
425 | bool with_ports = false; | ||
432 | int ret; | 426 | int ret; |
433 | 427 | ||
434 | if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || | 428 | if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || |
@@ -465,21 +459,15 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
465 | 459 | ||
466 | if (tb[IPSET_ATTR_PROTO]) { | 460 | if (tb[IPSET_ATTR_PROTO]) { |
467 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); | 461 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); |
462 | with_ports = ip_set_proto_with_ports(data.proto); | ||
468 | 463 | ||
469 | if (data.proto == 0) | 464 | if (data.proto == 0) |
470 | return -IPSET_ERR_INVALID_PROTO; | 465 | return -IPSET_ERR_INVALID_PROTO; |
471 | } else | 466 | } else |
472 | return -IPSET_ERR_MISSING_PROTO; | 467 | return -IPSET_ERR_MISSING_PROTO; |
473 | 468 | ||
474 | switch (data.proto) { | 469 | if (!(with_ports || data.proto == IPPROTO_ICMPV6)) |
475 | case IPPROTO_UDP: | ||
476 | case IPPROTO_TCP: | ||
477 | case IPPROTO_ICMPV6: | ||
478 | break; | ||
479 | default: | ||
480 | data.port = 0; | 470 | data.port = 0; |
481 | break; | ||
482 | } | ||
483 | 471 | ||
484 | if (tb[IPSET_ATTR_TIMEOUT]) { | 472 | if (tb[IPSET_ATTR_TIMEOUT]) { |
485 | if (!with_timeout(h->timeout)) | 473 | if (!with_timeout(h->timeout)) |
@@ -487,9 +475,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
487 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); | 475 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); |
488 | } | 476 | } |
489 | 477 | ||
490 | if (adt == IPSET_TEST || | 478 | if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { |
491 | !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || | ||
492 | !tb[IPSET_ATTR_PORT_TO]) { | ||
493 | ret = adtfn(set, &data, timeout); | 479 | ret = adtfn(set, &data, timeout); |
494 | return ip_set_eexist(ret, flags) ? 0 : ret; | 480 | return ip_set_eexist(ret, flags) ? 0 : ret; |
495 | } | 481 | } |
diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c index 34a165626ee9..8598676f2a05 100644 --- a/net/netfilter/ipset/ip_set_hash_netport.c +++ b/net/netfilter/ipset/ip_set_hash_netport.c | |||
@@ -170,6 +170,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
170 | struct hash_netport4_elem data = { .cidr = HOST_MASK }; | 170 | struct hash_netport4_elem data = { .cidr = HOST_MASK }; |
171 | u32 port, port_to; | 171 | u32 port, port_to; |
172 | u32 timeout = h->timeout; | 172 | u32 timeout = h->timeout; |
173 | bool with_ports = false; | ||
173 | int ret; | 174 | int ret; |
174 | 175 | ||
175 | if (unlikely(!tb[IPSET_ATTR_IP] || | 176 | if (unlikely(!tb[IPSET_ATTR_IP] || |
@@ -198,21 +199,15 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
198 | 199 | ||
199 | if (tb[IPSET_ATTR_PROTO]) { | 200 | if (tb[IPSET_ATTR_PROTO]) { |
200 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); | 201 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); |
202 | with_ports = ip_set_proto_with_ports(data.proto); | ||
201 | 203 | ||
202 | if (data.proto == 0) | 204 | if (data.proto == 0) |
203 | return -IPSET_ERR_INVALID_PROTO; | 205 | return -IPSET_ERR_INVALID_PROTO; |
204 | } else | 206 | } else |
205 | return -IPSET_ERR_MISSING_PROTO; | 207 | return -IPSET_ERR_MISSING_PROTO; |
206 | 208 | ||
207 | switch (data.proto) { | 209 | if (!(with_ports || data.proto == IPPROTO_ICMP)) |
208 | case IPPROTO_UDP: | ||
209 | case IPPROTO_TCP: | ||
210 | case IPPROTO_ICMP: | ||
211 | break; | ||
212 | default: | ||
213 | data.port = 0; | 210 | data.port = 0; |
214 | break; | ||
215 | } | ||
216 | 211 | ||
217 | if (tb[IPSET_ATTR_TIMEOUT]) { | 212 | if (tb[IPSET_ATTR_TIMEOUT]) { |
218 | if (!with_timeout(h->timeout)) | 213 | if (!with_timeout(h->timeout)) |
@@ -220,9 +215,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
220 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); | 215 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); |
221 | } | 216 | } |
222 | 217 | ||
223 | if (adt == IPSET_TEST || | 218 | if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { |
224 | !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || | ||
225 | !tb[IPSET_ATTR_PORT_TO]) { | ||
226 | ret = adtfn(set, &data, timeout); | 219 | ret = adtfn(set, &data, timeout); |
227 | return ip_set_eexist(ret, flags) ? 0 : ret; | 220 | return ip_set_eexist(ret, flags) ? 0 : ret; |
228 | } | 221 | } |
@@ -390,6 +383,7 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
390 | struct hash_netport6_elem data = { .cidr = HOST_MASK }; | 383 | struct hash_netport6_elem data = { .cidr = HOST_MASK }; |
391 | u32 port, port_to; | 384 | u32 port, port_to; |
392 | u32 timeout = h->timeout; | 385 | u32 timeout = h->timeout; |
386 | bool with_ports = false; | ||
393 | int ret; | 387 | int ret; |
394 | 388 | ||
395 | if (unlikely(!tb[IPSET_ATTR_IP] || | 389 | if (unlikely(!tb[IPSET_ATTR_IP] || |
@@ -418,21 +412,15 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
418 | 412 | ||
419 | if (tb[IPSET_ATTR_PROTO]) { | 413 | if (tb[IPSET_ATTR_PROTO]) { |
420 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); | 414 | data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); |
415 | with_ports = ip_set_proto_with_ports(data.proto); | ||
421 | 416 | ||
422 | if (data.proto == 0) | 417 | if (data.proto == 0) |
423 | return -IPSET_ERR_INVALID_PROTO; | 418 | return -IPSET_ERR_INVALID_PROTO; |
424 | } else | 419 | } else |
425 | return -IPSET_ERR_MISSING_PROTO; | 420 | return -IPSET_ERR_MISSING_PROTO; |
426 | 421 | ||
427 | switch (data.proto) { | 422 | if (!(with_ports || data.proto == IPPROTO_ICMPV6)) |
428 | case IPPROTO_UDP: | ||
429 | case IPPROTO_TCP: | ||
430 | case IPPROTO_ICMPV6: | ||
431 | break; | ||
432 | default: | ||
433 | data.port = 0; | 423 | data.port = 0; |
434 | break; | ||
435 | } | ||
436 | 424 | ||
437 | if (tb[IPSET_ATTR_TIMEOUT]) { | 425 | if (tb[IPSET_ATTR_TIMEOUT]) { |
438 | if (!with_timeout(h->timeout)) | 426 | if (!with_timeout(h->timeout)) |
@@ -440,9 +428,7 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
440 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); | 428 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); |
441 | } | 429 | } |
442 | 430 | ||
443 | if (adt == IPSET_TEST || | 431 | if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { |
444 | !(data.proto == IPPROTO_TCP || data.proto == IPPROTO_UDP) || | ||
445 | !tb[IPSET_ATTR_PORT_TO]) { | ||
446 | ret = adtfn(set, &data, timeout); | 432 | ret = adtfn(set, &data, timeout); |
447 | return ip_set_eexist(ret, flags) ? 0 : ret; | 433 | return ip_set_eexist(ret, flags) ? 0 : ret; |
448 | } | 434 | } |