Discussion:
ipset: bad timeout assignments
Vitezslav Samel
2014-10-10 08:56:21 UTC
Permalink
Hi!

I'm using ipset's hash:ip with timeout to ban bad behaving clients.
When using very long timeout ( > 2147483 ) the ipset's timeout gets
weird:

-- TEST 1 ----------------
+ uname -r
3.15.6
+ ipset --version
ipset v6.23, protocol version: 6
+ ipset create test hash:ip timeout 1111111
+ ipset add test 10.0.0.1
+ ipset add test 10.0.0.2 timeout 2000000
+ ipset add test 10.0.0.3 timeout 3000000
+ ipset list test
Name: test
Type: hash:ip
Revision: 3
Header: family inet hashsize 1024 maxelem 65536 timeout 1111111
Size in memory: 16720
References: 0
Members:
10.0.0.1 timeout 1111111
10.0.0.2 timeout 2000000
10.0.0.3 timeout 4294967
+ ipset destroy test
--------------------------

The 10.0.0.3 gets 4294967 timeout although I wanted timeout 3000000.

With hash:ip default timeout being >2147483 the test looks like this:

-- TEST 2 ----------------
+ ipset create test2 hash:ip timeout 3333333
+ ipset add test2 10.0.0.1
+ ipset add test2 10.0.0.2 timeout 2000000
+ ipset add test2 10.0.0.3 timeout 3000000
+ ipset list test2
Name: test2
Type: hash:ip
Revision: 3
Header: family inet hashsize 1024 maxelem 65536 timeout 3333333
Size in memory: 16720
References: 0
Members:
10.0.0.1 timeout 4294967
10.0.0.2 timeout 2000000
10.0.0.3 timeout 4294967
+ ipset destroy test2
--------------------------

Now 10.0.0.1 gets wrong timeout and 10.0.0.3 also.
The magic number 2147483 is (UINT_MAX/1000)/2 which makes me think this
is some signed/unsigned int problem somewhere.

The above tests were run on x86_64 machine; the same problem is on i686,
but wrongly assigned timeout is 2147483 instead of 4294967.

I also tried 3.16.2 kernel, but the bug is here too.

Could you, please, have a look at this problem?

Thanks,

Vita
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Jozsef Kadlecsik
2014-10-10 11:04:03 UTC
Permalink
Post by Vitezslav Samel
I'm using ipset's hash:ip with timeout to ban bad behaving clients.
When using very long timeout ( > 2147483 ) the ipset's timeout gets
-- TEST 1 ----------------
+ uname -r
3.15.6
+ ipset --version
ipset v6.23, protocol version: 6
+ ipset create test hash:ip timeout 1111111
+ ipset add test 10.0.0.1
+ ipset add test 10.0.0.2 timeout 2000000
+ ipset add test 10.0.0.3 timeout 3000000
+ ipset list test
Name: test
Type: hash:ip
Revision: 3
Header: family inet hashsize 1024 maxelem 65536 timeout 1111111
Size in memory: 16720
References: 0
10.0.0.1 timeout 1111111
10.0.0.2 timeout 2000000
10.0.0.3 timeout 4294967
+ ipset destroy test
--------------------------
The 10.0.0.3 gets 4294967 timeout although I wanted timeout 3000000.
-- TEST 2 ----------------
+ ipset create test2 hash:ip timeout 3333333
+ ipset add test2 10.0.0.1
+ ipset add test2 10.0.0.2 timeout 2000000
+ ipset add test2 10.0.0.3 timeout 3000000
+ ipset list test2
Name: test2
Type: hash:ip
Revision: 3
Header: family inet hashsize 1024 maxelem 65536 timeout 3333333
Size in memory: 16720
References: 0
10.0.0.1 timeout 4294967
10.0.0.2 timeout 2000000
10.0.0.3 timeout 4294967
+ ipset destroy test2
--------------------------
Now 10.0.0.1 gets wrong timeout and 10.0.0.3 also.
The magic number 2147483 is (UINT_MAX/1000)/2 which makes me think this
is some signed/unsigned int problem somewhere.
The above tests were run on x86_64 machine; the same problem is on i686,
but wrongly assigned timeout is 2147483 instead of 4294967.
I also tried 3.16.2 kernel, but the bug is here too.
Too large jiffies are converted automatically to MAX_JIFFY_OFFSET (i.e.
((LONG_MAX >> 1)-1)). That's a limitation in the kernel which cannot be
worked around. The only thing I could do is not to accept too large
timeout values.

Best regards,
Jozsef
-
E-mail : ***@blackhole.kfki.hu, ***@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 ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Vitezslav Samel
2014-10-10 11:14:04 UTC
Permalink
Post by Jozsef Kadlecsik
Post by Vitezslav Samel
I'm using ipset's hash:ip with timeout to ban bad behaving clients.
When using very long timeout ( > 2147483 ) the ipset's timeout gets
-- TEST 1 ----------------
+ uname -r
3.15.6
+ ipset --version
ipset v6.23, protocol version: 6
+ ipset create test hash:ip timeout 1111111
+ ipset add test 10.0.0.1
+ ipset add test 10.0.0.2 timeout 2000000
+ ipset add test 10.0.0.3 timeout 3000000
+ ipset list test
Name: test
Type: hash:ip
Revision: 3
Header: family inet hashsize 1024 maxelem 65536 timeout 1111111
Size in memory: 16720
References: 0
10.0.0.1 timeout 1111111
10.0.0.2 timeout 2000000
10.0.0.3 timeout 4294967
+ ipset destroy test
--------------------------
The 10.0.0.3 gets 4294967 timeout although I wanted timeout 3000000.
-- TEST 2 ----------------
+ ipset create test2 hash:ip timeout 3333333
+ ipset add test2 10.0.0.1
+ ipset add test2 10.0.0.2 timeout 2000000
+ ipset add test2 10.0.0.3 timeout 3000000
+ ipset list test2
Name: test2
Type: hash:ip
Revision: 3
Header: family inet hashsize 1024 maxelem 65536 timeout 3333333
Size in memory: 16720
References: 0
10.0.0.1 timeout 4294967
10.0.0.2 timeout 2000000
10.0.0.3 timeout 4294967
+ ipset destroy test2
--------------------------
Now 10.0.0.1 gets wrong timeout and 10.0.0.3 also.
The magic number 2147483 is (UINT_MAX/1000)/2 which makes me think this
is some signed/unsigned int problem somewhere.
The above tests were run on x86_64 machine; the same problem is on i686,
but wrongly assigned timeout is 2147483 instead of 4294967.
I also tried 3.16.2 kernel, but the bug is here too.
Too large jiffies are converted automatically to MAX_JIFFY_OFFSET (i.e.
((LONG_MAX >> 1)-1)). That's a limitation in the kernel which cannot be
worked around. The only thing I could do is not to accept too large
timeout values.
Even on machines with 64-bit long? That is weird.

Thanks,

Vita
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Jozsef Kadlecsik
2014-10-10 16:58:50 UTC
Permalink
Post by Vitezslav Samel
Post by Jozsef Kadlecsik
Post by Vitezslav Samel
I'm using ipset's hash:ip with timeout to ban bad behaving clients.
When using very long timeout ( > 2147483 ) the ipset's timeout gets
-- TEST 1 ----------------
+ uname -r
3.15.6
+ ipset --version
ipset v6.23, protocol version: 6
+ ipset create test hash:ip timeout 1111111
+ ipset add test 10.0.0.1
+ ipset add test 10.0.0.2 timeout 2000000
+ ipset add test 10.0.0.3 timeout 3000000
+ ipset list test
Name: test
Type: hash:ip
Revision: 3
Header: family inet hashsize 1024 maxelem 65536 timeout 1111111
Size in memory: 16720
References: 0
10.0.0.1 timeout 1111111
10.0.0.2 timeout 2000000
10.0.0.3 timeout 4294967
+ ipset destroy test
--------------------------
The 10.0.0.3 gets 4294967 timeout although I wanted timeout 3000000.
-- TEST 2 ----------------
+ ipset create test2 hash:ip timeout 3333333
+ ipset add test2 10.0.0.1
+ ipset add test2 10.0.0.2 timeout 2000000
+ ipset add test2 10.0.0.3 timeout 3000000
+ ipset list test2
Name: test2
Type: hash:ip
Revision: 3
Header: family inet hashsize 1024 maxelem 65536 timeout 3333333
Size in memory: 16720
References: 0
10.0.0.1 timeout 4294967
10.0.0.2 timeout 2000000
10.0.0.3 timeout 4294967
+ ipset destroy test2
--------------------------
Now 10.0.0.1 gets wrong timeout and 10.0.0.3 also.
The magic number 2147483 is (UINT_MAX/1000)/2 which makes me think this
is some signed/unsigned int problem somewhere.
The above tests were run on x86_64 machine; the same problem is on i686,
but wrongly assigned timeout is 2147483 instead of 4294967.
I also tried 3.16.2 kernel, but the bug is here too.
Too large jiffies are converted automatically to MAX_JIFFY_OFFSET (i.e.
((LONG_MAX >> 1)-1)). That's a limitation in the kernel which cannot be
worked around. The only thing I could do is not to accept too large
timeout values.
Even on machines with 64-bit long? That is weird.
You are right, I'll look into it. Part of the problem comes from a bad
protocol decision, because ipset passes timeout values as an u32 value
between userspace and kernel.

Best regards,
Jozsef
-
E-mail : ***@blackhole.kfki.hu, ***@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 ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Jozsef Kadlecsik
2014-10-10 21:19:15 UTC
Permalink
Post by Jozsef Kadlecsik
You are right, I'll look into it. Part of the problem comes from a bad
protocol decision, because ipset passes timeout values as an u32 value
between userspace and kernel.
Not sure whether it makes sense, but maybe an intermediate "fix" would
be to recognize, in userlevel, the too-large values, and properly clamp
them to the highest value representable by the protocol. Better than
wraparound that causes unexpectedly low timeouts, I think.
I'm thinking on just introducing a new attribute to carry u64 sized
timeout values.

Best regards,
Jozsef
-
E-mail : ***@blackhole.kfki.hu, ***@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 ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Jozsef Kadlecsik
2014-10-15 09:32:45 UTC
Permalink
Post by Vitezslav Samel
Post by Jozsef Kadlecsik
Post by Vitezslav Samel
I'm using ipset's hash:ip with timeout to ban bad behaving clients.
When using very long timeout ( > 2147483 ) the ipset's timeout gets
-- TEST 1 ----------------
+ uname -r
3.15.6
+ ipset --version
ipset v6.23, protocol version: 6
+ ipset create test hash:ip timeout 1111111
+ ipset add test 10.0.0.1
+ ipset add test 10.0.0.2 timeout 2000000
+ ipset add test 10.0.0.3 timeout 3000000
+ ipset list test
Name: test
Type: hash:ip
Revision: 3
Header: family inet hashsize 1024 maxelem 65536 timeout 1111111
Size in memory: 16720
References: 0
10.0.0.1 timeout 1111111
10.0.0.2 timeout 2000000
10.0.0.3 timeout 4294967
+ ipset destroy test
--------------------------
The 10.0.0.3 gets 4294967 timeout although I wanted timeout 3000000.
-- TEST 2 ----------------
+ ipset create test2 hash:ip timeout 3333333
+ ipset add test2 10.0.0.1
+ ipset add test2 10.0.0.2 timeout 2000000
+ ipset add test2 10.0.0.3 timeout 3000000
+ ipset list test2
Name: test2
Type: hash:ip
Revision: 3
Header: family inet hashsize 1024 maxelem 65536 timeout 3333333
Size in memory: 16720
References: 0
10.0.0.1 timeout 4294967
10.0.0.2 timeout 2000000
10.0.0.3 timeout 4294967
+ ipset destroy test2
--------------------------
Now 10.0.0.1 gets wrong timeout and 10.0.0.3 also.
The magic number 2147483 is (UINT_MAX/1000)/2 which makes me think this
is some signed/unsigned int problem somewhere.
The above tests were run on x86_64 machine; the same problem is on i686,
but wrongly assigned timeout is 2147483 instead of 4294967.
I also tried 3.16.2 kernel, but the bug is here too.
Too large jiffies are converted automatically to MAX_JIFFY_OFFSET (i.e.
((LONG_MAX >> 1)-1)). That's a limitation in the kernel which cannot be
worked around. The only thing I could do is not to accept too large
timeout values.
Even on machines with 64-bit long? That is weird.
I have re-checked and it is so: time values are stored in unsigned int
(see msecs_to_jiffies), so the maximal value in seconds is UINT_MAX/1000.
However, msecs_to_jiffies limits it further by checking negative values,
which halves the maximal value.

So this is beyond ipset itself. All I can do is to correct in the "ipset"
library what is the accepted maximal timeout value and change it from the
current UINT_MAX/1000 to (UINT_MAX/1000)/2.

Best regards,
Jozsef
-
E-mail : ***@blackhole.kfki.hu, ***@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 ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Vitezslav Samel
2014-10-15 10:05:04 UTC
Permalink
Post by Jozsef Kadlecsik
Post by Vitezslav Samel
Post by Jozsef Kadlecsik
Post by Vitezslav Samel
I'm using ipset's hash:ip with timeout to ban bad behaving clients.
When using very long timeout ( > 2147483 ) the ipset's timeout gets
-- TEST 1 ----------------
+ uname -r
3.15.6
+ ipset --version
ipset v6.23, protocol version: 6
+ ipset create test hash:ip timeout 1111111
+ ipset add test 10.0.0.1
+ ipset add test 10.0.0.2 timeout 2000000
+ ipset add test 10.0.0.3 timeout 3000000
+ ipset list test
Name: test
Type: hash:ip
Revision: 3
Header: family inet hashsize 1024 maxelem 65536 timeout 1111111
Size in memory: 16720
References: 0
10.0.0.1 timeout 1111111
10.0.0.2 timeout 2000000
10.0.0.3 timeout 4294967
+ ipset destroy test
--------------------------
The 10.0.0.3 gets 4294967 timeout although I wanted timeout 3000000.
-- TEST 2 ----------------
+ ipset create test2 hash:ip timeout 3333333
+ ipset add test2 10.0.0.1
+ ipset add test2 10.0.0.2 timeout 2000000
+ ipset add test2 10.0.0.3 timeout 3000000
+ ipset list test2
Name: test2
Type: hash:ip
Revision: 3
Header: family inet hashsize 1024 maxelem 65536 timeout 3333333
Size in memory: 16720
References: 0
10.0.0.1 timeout 4294967
10.0.0.2 timeout 2000000
10.0.0.3 timeout 4294967
+ ipset destroy test2
--------------------------
Now 10.0.0.1 gets wrong timeout and 10.0.0.3 also.
The magic number 2147483 is (UINT_MAX/1000)/2 which makes me think this
is some signed/unsigned int problem somewhere.
The above tests were run on x86_64 machine; the same problem is on i686,
but wrongly assigned timeout is 2147483 instead of 4294967.
I also tried 3.16.2 kernel, but the bug is here too.
Too large jiffies are converted automatically to MAX_JIFFY_OFFSET (i.e.
((LONG_MAX >> 1)-1)). That's a limitation in the kernel which cannot be
worked around. The only thing I could do is not to accept too large
timeout values.
Even on machines with 64-bit long? That is weird.
I have re-checked and it is so: time values are stored in unsigned int
(see msecs_to_jiffies), so the maximal value in seconds is UINT_MAX/1000.
However, msecs_to_jiffies limits it further by checking negative values,
which halves the maximal value.
So this is beyond ipset itself. All I can do is to correct in the "ipset"
library what is the accepted maximal timeout value and change it from the
current UINT_MAX/1000 to (UINT_MAX/1000)/2.
OK. So for me and other users the only solution to this problem is to
wait if you try to make some other way to specify the timeout greater
than (UINT_MAX/1000)/2 (i.e. about 24 days for current archs) - either
using u64 variables or something other.

Thank you very much,

Vita Samel
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Jozsef Kadlecsik
2014-10-15 11:20:29 UTC
Permalink
Post by Vitezslav Samel
Post by Jozsef Kadlecsik
Post by Vitezslav Samel
Post by Jozsef Kadlecsik
Post by Vitezslav Samel
I'm using ipset's hash:ip with timeout to ban bad behaving clients.
When using very long timeout ( > 2147483 ) the ipset's timeout gets
-- TEST 1 ----------------
+ uname -r
3.15.6
+ ipset --version
ipset v6.23, protocol version: 6
+ ipset create test hash:ip timeout 1111111
+ ipset add test 10.0.0.1
+ ipset add test 10.0.0.2 timeout 2000000
+ ipset add test 10.0.0.3 timeout 3000000
+ ipset list test
Name: test
Type: hash:ip
Revision: 3
Header: family inet hashsize 1024 maxelem 65536 timeout 1111111
Size in memory: 16720
References: 0
10.0.0.1 timeout 1111111
10.0.0.2 timeout 2000000
10.0.0.3 timeout 4294967
+ ipset destroy test
--------------------------
The 10.0.0.3 gets 4294967 timeout although I wanted timeout 3000000.
-- TEST 2 ----------------
+ ipset create test2 hash:ip timeout 3333333
+ ipset add test2 10.0.0.1
+ ipset add test2 10.0.0.2 timeout 2000000
+ ipset add test2 10.0.0.3 timeout 3000000
+ ipset list test2
Name: test2
Type: hash:ip
Revision: 3
Header: family inet hashsize 1024 maxelem 65536 timeout 3333333
Size in memory: 16720
References: 0
10.0.0.1 timeout 4294967
10.0.0.2 timeout 2000000
10.0.0.3 timeout 4294967
+ ipset destroy test2
--------------------------
Now 10.0.0.1 gets wrong timeout and 10.0.0.3 also.
The magic number 2147483 is (UINT_MAX/1000)/2 which makes me think this
is some signed/unsigned int problem somewhere.
The above tests were run on x86_64 machine; the same problem is on i686,
but wrongly assigned timeout is 2147483 instead of 4294967.
I also tried 3.16.2 kernel, but the bug is here too.
Too large jiffies are converted automatically to MAX_JIFFY_OFFSET (i.e.
((LONG_MAX >> 1)-1)). That's a limitation in the kernel which cannot be
worked around. The only thing I could do is not to accept too large
timeout values.
Even on machines with 64-bit long? That is weird.
I have re-checked and it is so: time values are stored in unsigned int
(see msecs_to_jiffies), so the maximal value in seconds is UINT_MAX/1000.
However, msecs_to_jiffies limits it further by checking negative values,
which halves the maximal value.
So this is beyond ipset itself. All I can do is to correct in the "ipset"
library what is the accepted maximal timeout value and change it from the
current UINT_MAX/1000 to (UINT_MAX/1000)/2.
OK. So for me and other users the only solution to this problem is to
wait if you try to make some other way to specify the timeout greater
than (UINT_MAX/1000)/2 (i.e. about 24 days for current archs) - either
using u64 variables or something other.
I plan to keep the timeout values internally to ipset and feed the kernel
core with the max value it can handle as and until required.

I don't plan to change the ipset protocol by introducing a new attribute:
timeout is carried in u32, so if that'll be kept separatedly, then the max
136 years timeout value should be enough :-)

Best regards,
Jozsef
-
E-mail : ***@blackhole.kfki.hu, ***@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 ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Loading...