Patchwork [2/2] netnet,netportnet: Fix value range support for IPv4

login
register
mail settings
Submitter Sergey Popovich
Date May 5, 2014, 8:07 a.m.
Message ID <013ebb6b972846e27933e99c2d016492c58564a6.1399275196.git.popovich_sergei@mail.ru>
Download mbox | patch
Permalink /patch/345612/
State Accepted
Delegated to: Jozsef Kadlecsik
Headers show

Comments

Sergey Popovich - May 5, 2014, 8:07 a.m.
Ranges of values are broken with hash:net,net and hash:net,port,net.

hash:net,net
Jozsef Kadlecsik - May 6, 2014, 9:06 a.m.
On Mon, 5 May 2014, Sergey Popovich wrote:

> Ranges of values are broken with hash:net,net and hash:net,port,net.
> 
> hash:net,net
> ============
> 
>    # ipset create test-nn hash:net,net
>    # ipset add test-nn 10.0.10.1-10.0.10.127,10.0.0.0/8
> 
>    # ipset list test-nn
>    Name: test-nn
>    Type: hash:net,net
>    Revision: 0
>    Header: family inet hashsize 1024 maxelem 65536
>    Size in memory: 16960
>    References: 0
>    Members:
>    10.0.10.1,10.0.0.0/8
> 
>    # ipset test test-nn 10.0.10.65,10.0.0.1
>    10.0.10.65,10.0.0.1 is NOT in set test-nn.
>    # ipset test test-nn 10.0.10.1,10.0.0.1
>    10.0.10.1,10.0.0.1 is in set test-nn.
> 
> hash:net,port,net
> =================
> 
>    # ipset create test-npn hash:net,port,net
>    # ipset add test-npn 10.0.10.1-10.0.10.127,tcp:80,10.0.0.0/8
>    # ipset list test-npn
>    Name: test-npn
>    Type: hash:net,port,net
>    Revision: 0
>    Header: family inet hashsize 1024 maxelem 65536
>    Size in memory: 17344
>    References: 0
>    Members:
>    10.0.10.8/29,tcp:80,10.0.0.0
>    10.0.10.16/28,tcp:80,10.0.0.0
>    10.0.10.2/31,tcp:80,10.0.0.0
>    10.0.10.64/26,tcp:80,10.0.0.0
>    10.0.10.32/27,tcp:80,10.0.0.0
>    10.0.10.4/30,tcp:80,10.0.0.0
>    10.0.10.1,tcp:80,10.0.0.0
>    # ipset list test-npn
>    # ipset test test-npn 10.0.10.126,tcp:80,10.0.0.2
>    10.0.10.126,tcp:80,10.0.0.2 is NOT in set test-npn.
>    # ipset test test-npn 10.0.10.126,tcp:80,10.0.0.0
>    10.0.10.126,tcp:80,10.0.0.0 is in set test-npn.
> 
>    # ipset create test-npn hash:net,port,net
>    # ipset add test-npn 10.0.10.0/24,tcp:80-81,10.0.0.0/8
>    # ipset list test-npn
>    Name: test-npn
>    Type: hash:net,port,net
>    Revision: 0
>    Header: family inet hashsize 1024 maxelem 65536
>    Size in memory: 17024
>    References: 0
>    Members:
>    10.0.10.0,tcp:80,10.0.0.0
>    10.0.10.0,tcp:81,10.0.0.0
>    # ipset test test-npn 10.0.10.126,tcp:80,10.0.0.0
>    10.0.10.126,tcp:80,10.0.0.0 is NOT in set test-npn.
>    # ipset test test-npn 10.0.10.0,tcp:80,10.0.0.0
>    10.0.10.0,tcp:80,10.0.0.0 is in set test-npn.
> 
> Correctly setup from..to variables where no IPSET_ATTR_IP_TO{,2}
> attribute is given, so in range processing loop we construct proper
> cidr value. Check whenever we have no ranges and can short cut in
> hash:net,net properly. Use unlikely() where appropriate, to comply
> with other modules.

Good catch, patch is applied. Thanks.

Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences
          H-1525 Budapest 114, POB. 49, Hungary
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

============

   # ipset create test-nn hash:net,net
   # ipset add test-nn 10.0.10.1-10.0.10.127,10.0.0.0/8

   # ipset list test-nn
   Name: test-nn
   Type: hash:net,net
   Revision: 0
   Header: family inet hashsize 1024 maxelem 65536
   Size in memory: 16960
   References: 0
   Members:
   10.0.10.1,10.0.0.0/8

   # ipset test test-nn 10.0.10.65,10.0.0.1
   10.0.10.65,10.0.0.1 is NOT in set test-nn.
   # ipset test test-nn 10.0.10.1,10.0.0.1
   10.0.10.1,10.0.0.1 is in set test-nn.

hash:net,port,net
=================

   # ipset create test-npn hash:net,port,net
   # ipset add test-npn 10.0.10.1-10.0.10.127,tcp:80,10.0.0.0/8
   # ipset list test-npn
   Name: test-npn
   Type: hash:net,port,net
   Revision: 0
   Header: family inet hashsize 1024 maxelem 65536
   Size in memory: 17344
   References: 0
   Members:
   10.0.10.8/29,tcp:80,10.0.0.0
   10.0.10.16/28,tcp:80,10.0.0.0
   10.0.10.2/31,tcp:80,10.0.0.0
   10.0.10.64/26,tcp:80,10.0.0.0
   10.0.10.32/27,tcp:80,10.0.0.0
   10.0.10.4/30,tcp:80,10.0.0.0
   10.0.10.1,tcp:80,10.0.0.0
   # ipset list test-npn
   # ipset test test-npn 10.0.10.126,tcp:80,10.0.0.2
   10.0.10.126,tcp:80,10.0.0.2 is NOT in set test-npn.
   # ipset test test-npn 10.0.10.126,tcp:80,10.0.0.0
   10.0.10.126,tcp:80,10.0.0.0 is in set test-npn.

   # ipset create test-npn hash:net,port,net
   # ipset add test-npn 10.0.10.0/24,tcp:80-81,10.0.0.0/8
   # ipset list test-npn
   Name: test-npn
   Type: hash:net,port,net
   Revision: 0
   Header: family inet hashsize 1024 maxelem 65536
   Size in memory: 17024
   References: 0
   Members:
   10.0.10.0,tcp:80,10.0.0.0
   10.0.10.0,tcp:81,10.0.0.0
   # ipset test test-npn 10.0.10.126,tcp:80,10.0.0.0
   10.0.10.126,tcp:80,10.0.0.0 is NOT in set test-npn.
   # ipset test test-npn 10.0.10.0,tcp:80,10.0.0.0
   10.0.10.0,tcp:80,10.0.0.0 is in set test-npn.

Correctly setup from..to variables where no IPSET_ATTR_IP_TO{,2}
attribute is given, so in range processing loop we construct proper
cidr value. Check whenever we have no ranges and can short cut in
hash:net,net properly. Use unlikely() where appropriate, to comply
with other modules.

Signed-off-by: Sergey Popovich <popovich_sergei@mail.ru>
---
 kernel/net/netfilter/ipset/ip_set_hash_netnet.c     |   13 +++++++------
 kernel/net/netfilter/ipset/ip_set_hash_netportnet.c |    6 ++++--
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/kernel/net/netfilter/ipset/ip_set_hash_netnet.c b/kernel/net/netfilter/ipset/ip_set_hash_netnet.c
index 3e99987..96b1313 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_netnet.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_netnet.c
@@ -203,7 +203,7 @@  hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 			flags |= (IPSET_FLAG_NOMATCH << 16);
 	}
 
-	if (adt == IPSET_TEST || !(tb[IPSET_ATTR_IP_TO] &&
+	if (adt == IPSET_TEST || !(tb[IPSET_ATTR_IP_TO] ||
 				   tb[IPSET_ATTR_IP2_TO])) {
 		e.ip[0] = htonl(ip & ip_set_hostmask(e.cidr[0]));
 		e.ip[1] = htonl(ip2_from & ip_set_hostmask(e.cidr[1]));
@@ -219,9 +219,10 @@  hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 			return ret;
 		if (ip_to < ip)
 			swap(ip, ip_to);
-		if (ip + UINT_MAX == ip_to)
+		if (unlikely(ip + UINT_MAX == ip_to))
 			return -IPSET_ERR_HASH_RANGE;
-	}
+	} else
+		ip_set_mask_from_to(ip, ip_to, e.cidr[0]);
 
 	ip2_to = ip2_from;
 	if (tb[IPSET_ATTR_IP2_TO]) {
@@ -230,10 +231,10 @@  hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 			return ret;
 		if (ip2_to < ip2_from)
 			swap(ip2_from, ip2_to);
-		if (ip2_from + UINT_MAX == ip2_to)
+		if (unlikely(ip2_from + UINT_MAX == ip2_to))
 			return -IPSET_ERR_HASH_RANGE;
-
-	}
+	} else
+		ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]);
 
 	if (retried)
 		ip = ntohl(h->next.ip[0]);
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_netportnet.c b/kernel/net/netfilter/ipset/ip_set_hash_netportnet.c
index c0d2ba7..2f00343 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_netportnet.c
+++ b/kernel/net/netfilter/ipset/ip_set_hash_netportnet.c
@@ -257,7 +257,8 @@  hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 			swap(ip, ip_to);
 		if (unlikely(ip + UINT_MAX == ip_to))
 			return -IPSET_ERR_HASH_RANGE;
-	}
+	} else
+		ip_set_mask_from_to(ip, ip_to, e.cidr[0]);
 
 	port_to = port = ntohs(e.port);
 	if (tb[IPSET_ATTR_PORT_TO]) {
@@ -275,7 +276,8 @@  hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 			swap(ip2_from, ip2_to);
 		if (unlikely(ip2_from + UINT_MAX == ip2_to))
 			return -IPSET_ERR_HASH_RANGE;
-	}
+	} else
+		ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]);
 
 	if (retried)
 		ip = ntohl(h->next.ip[0]);