diff options
-rw-r--r-- | include/linux/netfilter/ipset/ip_set.h | 8 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_hash_ipportnet.c | 14 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_hash_net.c | 14 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_hash_netiface.c | 14 | ||||
-rw-r--r-- | net/netfilter/ipset/ip_set_hash_netport.c | 14 |
5 files changed, 40 insertions, 24 deletions
diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h index 7958e84a65af..970187187f5b 100644 --- a/include/linux/netfilter/ipset/ip_set.h +++ b/include/linux/netfilter/ipset/ip_set.h | |||
@@ -200,6 +200,14 @@ ip_set_eexist(int ret, u32 flags) | |||
200 | return ret == -IPSET_ERR_EXIST && (flags & IPSET_FLAG_EXIST); | 200 | return ret == -IPSET_ERR_EXIST && (flags & IPSET_FLAG_EXIST); |
201 | } | 201 | } |
202 | 202 | ||
203 | /* Match elements marked with nomatch */ | ||
204 | static inline bool | ||
205 | ip_set_enomatch(int ret, u32 flags, enum ipset_adt adt) | ||
206 | { | ||
207 | return adt == IPSET_TEST && | ||
208 | ret == -ENOTEMPTY && ((flags >> 16) & IPSET_FLAG_NOMATCH); | ||
209 | } | ||
210 | |||
203 | /* Check the NLA_F_NET_BYTEORDER flag */ | 211 | /* Check the NLA_F_NET_BYTEORDER flag */ |
204 | static inline bool | 212 | static inline bool |
205 | ip_set_attr_netorder(struct nlattr *tb[], int type) | 213 | ip_set_attr_netorder(struct nlattr *tb[], int type) |
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index 10a30b4fc7db..b4836c81fbb7 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c | |||
@@ -279,10 +279,10 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
279 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); | 279 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); |
280 | } | 280 | } |
281 | 281 | ||
282 | if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) { | 282 | if (tb[IPSET_ATTR_CADT_FLAGS]) { |
283 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); | 283 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); |
284 | if (cadt_flags & IPSET_FLAG_NOMATCH) | 284 | if (cadt_flags & IPSET_FLAG_NOMATCH) |
285 | flags |= (cadt_flags << 16); | 285 | flags |= (IPSET_FLAG_NOMATCH << 16); |
286 | } | 286 | } |
287 | 287 | ||
288 | with_ports = with_ports && tb[IPSET_ATTR_PORT_TO]; | 288 | with_ports = with_ports && tb[IPSET_ATTR_PORT_TO]; |
@@ -292,7 +292,8 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
292 | data.ip = htonl(ip); | 292 | data.ip = htonl(ip); |
293 | data.ip2 = htonl(ip2_from & ip_set_hostmask(data.cidr + 1)); | 293 | data.ip2 = htonl(ip2_from & ip_set_hostmask(data.cidr + 1)); |
294 | ret = adtfn(set, &data, timeout, flags); | 294 | ret = adtfn(set, &data, timeout, flags); |
295 | return ip_set_eexist(ret, flags) ? 0 : ret; | 295 | return ip_set_enomatch(ret, flags, adt) ? 1 : |
296 | ip_set_eexist(ret, flags) ? 0 : ret; | ||
296 | } | 297 | } |
297 | 298 | ||
298 | ip_to = ip; | 299 | ip_to = ip; |
@@ -610,15 +611,16 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
610 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); | 611 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); |
611 | } | 612 | } |
612 | 613 | ||
613 | if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) { | 614 | if (tb[IPSET_ATTR_CADT_FLAGS]) { |
614 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); | 615 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); |
615 | if (cadt_flags & IPSET_FLAG_NOMATCH) | 616 | if (cadt_flags & IPSET_FLAG_NOMATCH) |
616 | flags |= (cadt_flags << 16); | 617 | flags |= (IPSET_FLAG_NOMATCH << 16); |
617 | } | 618 | } |
618 | 619 | ||
619 | if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { | 620 | if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { |
620 | ret = adtfn(set, &data, timeout, flags); | 621 | ret = adtfn(set, &data, timeout, flags); |
621 | return ip_set_eexist(ret, flags) ? 0 : ret; | 622 | return ip_set_enomatch(ret, flags, adt) ? 1 : |
623 | ip_set_eexist(ret, flags) ? 0 : ret; | ||
622 | } | 624 | } |
623 | 625 | ||
624 | port = ntohs(data.port); | 626 | port = ntohs(data.port); |
diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c index d6a59154d710..6dbe0afc5a8d 100644 --- a/net/netfilter/ipset/ip_set_hash_net.c +++ b/net/netfilter/ipset/ip_set_hash_net.c | |||
@@ -225,16 +225,17 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
225 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); | 225 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); |
226 | } | 226 | } |
227 | 227 | ||
228 | if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) { | 228 | if (tb[IPSET_ATTR_CADT_FLAGS]) { |
229 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); | 229 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); |
230 | if (cadt_flags & IPSET_FLAG_NOMATCH) | 230 | if (cadt_flags & IPSET_FLAG_NOMATCH) |
231 | flags |= (cadt_flags << 16); | 231 | flags |= (IPSET_FLAG_NOMATCH << 16); |
232 | } | 232 | } |
233 | 233 | ||
234 | if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) { | 234 | if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) { |
235 | data.ip = htonl(ip & ip_set_hostmask(data.cidr)); | 235 | data.ip = htonl(ip & ip_set_hostmask(data.cidr)); |
236 | ret = adtfn(set, &data, timeout, flags); | 236 | ret = adtfn(set, &data, timeout, flags); |
237 | return ip_set_eexist(ret, flags) ? 0 : ret; | 237 | return ip_set_enomatch(ret, flags, adt) ? 1 : |
238 | ip_set_eexist(ret, flags) ? 0 : ret; | ||
238 | } | 239 | } |
239 | 240 | ||
240 | ip_to = ip; | 241 | ip_to = ip; |
@@ -466,15 +467,16 @@ hash_net6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
466 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); | 467 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); |
467 | } | 468 | } |
468 | 469 | ||
469 | if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) { | 470 | if (tb[IPSET_ATTR_CADT_FLAGS]) { |
470 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); | 471 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); |
471 | if (cadt_flags & IPSET_FLAG_NOMATCH) | 472 | if (cadt_flags & IPSET_FLAG_NOMATCH) |
472 | flags |= (cadt_flags << 16); | 473 | flags |= (IPSET_FLAG_NOMATCH << 16); |
473 | } | 474 | } |
474 | 475 | ||
475 | ret = adtfn(set, &data, timeout, flags); | 476 | ret = adtfn(set, &data, timeout, flags); |
476 | 477 | ||
477 | return ip_set_eexist(ret, flags) ? 0 : ret; | 478 | return ip_set_enomatch(ret, flags, adt) ? 1 : |
479 | ip_set_eexist(ret, flags) ? 0 : ret; | ||
478 | } | 480 | } |
479 | 481 | ||
480 | /* Create hash:ip type of sets */ | 482 | /* Create hash:ip type of sets */ |
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c index f2b0a3c30130..248162020d80 100644 --- a/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/net/netfilter/ipset/ip_set_hash_netiface.c | |||
@@ -396,13 +396,14 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
396 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); | 396 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); |
397 | if (cadt_flags & IPSET_FLAG_PHYSDEV) | 397 | if (cadt_flags & IPSET_FLAG_PHYSDEV) |
398 | data.physdev = 1; | 398 | data.physdev = 1; |
399 | if (adt == IPSET_ADD && (cadt_flags & IPSET_FLAG_NOMATCH)) | 399 | if (cadt_flags & IPSET_FLAG_NOMATCH) |
400 | flags |= (cadt_flags << 16); | 400 | flags |= (IPSET_FLAG_NOMATCH << 16); |
401 | } | 401 | } |
402 | if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) { | 402 | if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) { |
403 | data.ip = htonl(ip & ip_set_hostmask(data.cidr)); | 403 | data.ip = htonl(ip & ip_set_hostmask(data.cidr)); |
404 | ret = adtfn(set, &data, timeout, flags); | 404 | ret = adtfn(set, &data, timeout, flags); |
405 | return ip_set_eexist(ret, flags) ? 0 : ret; | 405 | return ip_set_enomatch(ret, flags, adt) ? 1 : |
406 | ip_set_eexist(ret, flags) ? 0 : ret; | ||
406 | } | 407 | } |
407 | 408 | ||
408 | if (tb[IPSET_ATTR_IP_TO]) { | 409 | if (tb[IPSET_ATTR_IP_TO]) { |
@@ -704,13 +705,14 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
704 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); | 705 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); |
705 | if (cadt_flags & IPSET_FLAG_PHYSDEV) | 706 | if (cadt_flags & IPSET_FLAG_PHYSDEV) |
706 | data.physdev = 1; | 707 | data.physdev = 1; |
707 | if (adt == IPSET_ADD && (cadt_flags & IPSET_FLAG_NOMATCH)) | 708 | if (cadt_flags & IPSET_FLAG_NOMATCH) |
708 | flags |= (cadt_flags << 16); | 709 | flags |= (IPSET_FLAG_NOMATCH << 16); |
709 | } | 710 | } |
710 | 711 | ||
711 | ret = adtfn(set, &data, timeout, flags); | 712 | ret = adtfn(set, &data, timeout, flags); |
712 | 713 | ||
713 | return ip_set_eexist(ret, flags) ? 0 : ret; | 714 | return ip_set_enomatch(ret, flags, adt) ? 1 : |
715 | ip_set_eexist(ret, flags) ? 0 : ret; | ||
714 | } | 716 | } |
715 | 717 | ||
716 | /* Create hash:ip type of sets */ | 718 | /* Create hash:ip type of sets */ |
diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c index 349deb672a2d..57b0550a0b0d 100644 --- a/net/netfilter/ipset/ip_set_hash_netport.c +++ b/net/netfilter/ipset/ip_set_hash_netport.c | |||
@@ -272,16 +272,17 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
272 | 272 | ||
273 | with_ports = with_ports && tb[IPSET_ATTR_PORT_TO]; | 273 | with_ports = with_ports && tb[IPSET_ATTR_PORT_TO]; |
274 | 274 | ||
275 | if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) { | 275 | if (tb[IPSET_ATTR_CADT_FLAGS]) { |
276 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); | 276 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); |
277 | if (cadt_flags & IPSET_FLAG_NOMATCH) | 277 | if (cadt_flags & IPSET_FLAG_NOMATCH) |
278 | flags |= (cadt_flags << 16); | 278 | flags |= (IPSET_FLAG_NOMATCH << 16); |
279 | } | 279 | } |
280 | 280 | ||
281 | if (adt == IPSET_TEST || !(with_ports || tb[IPSET_ATTR_IP_TO])) { | 281 | if (adt == IPSET_TEST || !(with_ports || tb[IPSET_ATTR_IP_TO])) { |
282 | data.ip = htonl(ip & ip_set_hostmask(data.cidr + 1)); | 282 | data.ip = htonl(ip & ip_set_hostmask(data.cidr + 1)); |
283 | ret = adtfn(set, &data, timeout, flags); | 283 | ret = adtfn(set, &data, timeout, flags); |
284 | return ip_set_eexist(ret, flags) ? 0 : ret; | 284 | return ip_set_enomatch(ret, flags, adt) ? 1 : |
285 | ip_set_eexist(ret, flags) ? 0 : ret; | ||
285 | } | 286 | } |
286 | 287 | ||
287 | port = port_to = ntohs(data.port); | 288 | port = port_to = ntohs(data.port); |
@@ -561,15 +562,16 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[], | |||
561 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); | 562 | timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); |
562 | } | 563 | } |
563 | 564 | ||
564 | if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) { | 565 | if (tb[IPSET_ATTR_CADT_FLAGS]) { |
565 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); | 566 | u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); |
566 | if (cadt_flags & IPSET_FLAG_NOMATCH) | 567 | if (cadt_flags & IPSET_FLAG_NOMATCH) |
567 | flags |= (cadt_flags << 16); | 568 | flags |= (IPSET_FLAG_NOMATCH << 16); |
568 | } | 569 | } |
569 | 570 | ||
570 | if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { | 571 | if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { |
571 | ret = adtfn(set, &data, timeout, flags); | 572 | ret = adtfn(set, &data, timeout, flags); |
572 | return ip_set_eexist(ret, flags) ? 0 : ret; | 573 | return ip_set_enomatch(ret, flags, adt) ? 1 : |
574 | ip_set_eexist(ret, flags) ? 0 : ret; | ||
573 | } | 575 | } |
574 | 576 | ||
575 | port = ntohs(data.port); | 577 | port = ntohs(data.port); |