aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter/ipset/ip_set.h8
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportnet.c14
-rw-r--r--net/netfilter/ipset/ip_set_hash_net.c14
-rw-r--r--net/netfilter/ipset/ip_set_hash_netiface.c14
-rw-r--r--net/netfilter/ipset/ip_set_hash_netport.c14
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 */
204static inline bool
205ip_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 */
204static inline bool 212static inline bool
205ip_set_attr_netorder(struct nlattr *tb[], int type) 213ip_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);