netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH iproute2] get_rate: detect 32bit overflows
@ 2013-06-02 18:51 Eric Dumazet
  2013-06-02 21:30 ` Eric Dumazet
  2013-06-02 21:36 ` [PATCH v2 " Eric Dumazet
  0 siblings, 2 replies; 9+ messages in thread
From: Eric Dumazet @ 2013-06-02 18:51 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

Current rate limit is 34.359.738.360 bit per second, and
unfortunately 40Gbps links are above it.

overflows in get_rate() are currently not detected, and some
users are confused. Let's detect this and complain.

Note that some qdisc are ready to get extended range, but this will
need additional attributes and new iproute2

Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 tc/tc_util.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/tc/tc_util.c b/tc/tc_util.c
index 8e62a01..0a25250 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -146,21 +146,26 @@ static const struct rate_suffix {
 int get_rate(unsigned *rate, const char *str)
 {
 	char *p;
-	double bps = strtod(str, &p);
+	long long bps = strtoll(str, &p, 0);
 	const struct rate_suffix *s;
 
 	if (p == str)
 		return -1;
 
+	bps /= 8; /* -> bytes per second */
 	if (*p == '\0') {
-		*rate = bps / 8.;	/* assume bits/sec */
+common:
+		*rate = bps;
+		/* detect if an overflow happened */
+		if (*rate != bps)
+			return -1;
 		return 0;
 	}
 
 	for (s = suffixes; s->name; ++s) {
 		if (strcasecmp(s->name, p) == 0) {
-			*rate = (bps * s->scale) / 8.;
-			return 0;
+			bps *= s->scale;
+			goto common;
 		}
 	}
 

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH iproute2] get_rate: detect 32bit overflows
  2013-06-02 18:51 [PATCH iproute2] get_rate: detect 32bit overflows Eric Dumazet
@ 2013-06-02 21:30 ` Eric Dumazet
  2013-06-02 21:36 ` [PATCH v2 " Eric Dumazet
  1 sibling, 0 replies; 9+ messages in thread
From: Eric Dumazet @ 2013-06-02 21:30 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

On Sun, 2013-06-02 at 11:51 -0700, Eric Dumazet wrote:
> Current rate limit is 34.359.738.360 bit per second, and
> unfortunately 40Gbps links are above it.
> 
> overflows in get_rate() are currently not detected, and some
> users are confused. Let's detect this and complain.
> 
> Note that some qdisc are ready to get extended range, but this will
> need additional attributes and new iproute2
> 

Hmpf, patch is buggy, I'll send a v2

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 iproute2] get_rate: detect 32bit overflows
  2013-06-02 18:51 [PATCH iproute2] get_rate: detect 32bit overflows Eric Dumazet
  2013-06-02 21:30 ` Eric Dumazet
@ 2013-06-02 21:36 ` Eric Dumazet
  2013-06-03 14:37   ` Ben Hutchings
  2013-06-07 16:25   ` Stephen Hemminger
  1 sibling, 2 replies; 9+ messages in thread
From: Eric Dumazet @ 2013-06-02 21:36 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

Current rate limit is 34.359.738.360 bit per second, and
unfortunately 40Gbps links are above it.

overflows in get_rate() are currently not detected, and some
users are confused. Let's detect this and complain.

Note that some qdisc are ready to get extended range, but this will
need additional attributes and new iproute2

Signed-off-by: Eric Dumazet <edumazet@google.com>
---
v2: divide by 8 only at the right time

 tc/tc_util.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/tc/tc_util.c b/tc/tc_util.c
index 8e62a01..8ca9d4e 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -146,21 +146,26 @@ static const struct rate_suffix {
 int get_rate(unsigned *rate, const char *str)
 {
 	char *p;
-	double bps = strtod(str, &p);
+	long long bps = strtoll(str, &p, 0);
 	const struct rate_suffix *s;
 
 	if (p == str)
 		return -1;
 
 	if (*p == '\0') {
-		*rate = bps / 8.;	/* assume bits/sec */
+common:
+		bps /= 8; /* -> bytes per second */
+		*rate = bps;
+		/* detect if an overflow happened */
+		if (*rate != bps)
+			return -1;
 		return 0;
 	}
 
 	for (s = suffixes; s->name; ++s) {
 		if (strcasecmp(s->name, p) == 0) {
-			*rate = (bps * s->scale) / 8.;
-			return 0;
+			bps *= s->scale;
+			goto common;
 		}
 	}
 

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 iproute2] get_rate: detect 32bit overflows
  2013-06-02 21:36 ` [PATCH v2 " Eric Dumazet
@ 2013-06-03 14:37   ` Ben Hutchings
  2013-06-03 15:19     ` Eric Dumazet
  2013-06-07 16:25   ` Stephen Hemminger
  1 sibling, 1 reply; 9+ messages in thread
From: Ben Hutchings @ 2013-06-03 14:37 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Stephen Hemminger, netdev

On Sun, 2013-06-02 at 14:36 -0700, Eric Dumazet wrote:
> Current rate limit is 34.359.738.360 bit per second, and
> unfortunately 40Gbps links are above it.
> 
> overflows in get_rate() are currently not detected, and some
> users are confused. Let's detect this and complain.
> 
> Note that some qdisc are ready to get extended range, but this will
> need additional attributes and new iproute2
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
> v2: divide by 8 only at the right time
> 
>  tc/tc_util.c |   13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/tc/tc_util.c b/tc/tc_util.c
> index 8e62a01..8ca9d4e 100644
> --- a/tc/tc_util.c
> +++ b/tc/tc_util.c
> @@ -146,21 +146,26 @@ static const struct rate_suffix {
>  int get_rate(unsigned *rate, const char *str)
>  {
>  	char *p;
> -	double bps = strtod(str, &p);
> +	long long bps = strtoll(str, &p, 0);
>  	const struct rate_suffix *s;
>  
>  	if (p == str)
>  		return -1;
>  
>  	if (*p == '\0') {
> -		*rate = bps / 8.;	/* assume bits/sec */
> +common:
> +		bps /= 8; /* -> bytes per second */
> +		*rate = bps;
> +		/* detect if an overflow happened */
> +		if (*rate != bps)
> +			return -1;
>  		return 0;
>  	}
>  
>  	for (s = suffixes; s->name; ++s) {
>  		if (strcasecmp(s->name, p) == 0) {
> -			*rate = (bps * s->scale) / 8.;
> -			return 0;
> +			bps *= s->scale;
> +			goto common;
>  		}
>  	}

This would be more understandable without a goto.  I think this ordering
would work:

	for (s = suffixes; ...) {
		if (...) {
			bps *= s->scale;
			p += strlen(s->name);
			break;
		}
	}

	if (*p)
		return -1; /* unrecognised suffix */

	bps /= 8;
	...

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 iproute2] get_rate: detect 32bit overflows
  2013-06-03 14:37   ` Ben Hutchings
@ 2013-06-03 15:19     ` Eric Dumazet
  2013-06-03 15:36       ` Ben Hutchings
  0 siblings, 1 reply; 9+ messages in thread
From: Eric Dumazet @ 2013-06-03 15:19 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: Stephen Hemminger, netdev

On Mon, 2013-06-03 at 15:37 +0100, Ben Hutchings wrote:

> This would be more understandable without a goto.  I think this ordering
> would work:

Yeah you're right, thanks !

[PATCH v3] get_rate: detect 32bit overflows

Current rate limit is 34.359.738.360 bit per second, and
unfortunately 40Gbps links are above it.

overflows in get_rate() are currently not detected, and some
users are confused. Let's detect this and complain.

Note that some qdisc are ready to get extended range, but this will
need additional attributes and new iproute2

Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 tc/tc_util.c |   22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/tc/tc_util.c b/tc/tc_util.c
index 8e62a01..912216c 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -146,25 +146,29 @@ static const struct rate_suffix {
 int get_rate(unsigned *rate, const char *str)
 {
 	char *p;
-	double bps = strtod(str, &p);
+	long long bps = strtoll(str, &p, 0);
 	const struct rate_suffix *s;
 
 	if (p == str)
 		return -1;
 
-	if (*p == '\0') {
-		*rate = bps / 8.;	/* assume bits/sec */
-		return 0;
-	}
-
 	for (s = suffixes; s->name; ++s) {
 		if (strcasecmp(s->name, p) == 0) {
-			*rate = (bps * s->scale) / 8.;
-			return 0;
+			bps *= s->scale;
+			p += strlen(p);
+			break;
 		}
 	}
 
-	return -1;
+	if (*p)
+		return -1; /* unknown suffix */
+
+	bps /= 8; /* -> bytes per second */
+	*rate = bps;
+	/* detect if an overflow happened */
+	if (*rate != bps)
+		return -1;
+	return 0;
 }
 
 void print_rate(char *buf, int len, __u32 rate)

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 iproute2] get_rate: detect 32bit overflows
  2013-06-03 15:19     ` Eric Dumazet
@ 2013-06-03 15:36       ` Ben Hutchings
  2013-06-03 15:51         ` Eric Dumazet
  0 siblings, 1 reply; 9+ messages in thread
From: Ben Hutchings @ 2013-06-03 15:36 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Stephen Hemminger, netdev

On Mon, 2013-06-03 at 08:19 -0700, Eric Dumazet wrote:
> On Mon, 2013-06-03 at 15:37 +0100, Ben Hutchings wrote:
> 
> > This would be more understandable without a goto.  I think this ordering
> > would work:
> 
> Yeah you're right, thanks !
> 
> [PATCH v3] get_rate: detect 32bit overflows
> 
> Current rate limit is 34.359.738.360 bit per second, and
> unfortunately 40Gbps links are above it.
> 
> overflows in get_rate() are currently not detected, and some
> users are confused. Let's detect this and complain.
> 
> Note that some qdisc are ready to get extended range, but this will
> need additional attributes and new iproute2
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
>  tc/tc_util.c |   22 +++++++++++++---------
>  1 file changed, 13 insertions(+), 9 deletions(-)
> 
> diff --git a/tc/tc_util.c b/tc/tc_util.c
> index 8e62a01..912216c 100644
> --- a/tc/tc_util.c
> +++ b/tc/tc_util.c
> @@ -146,25 +146,29 @@ static const struct rate_suffix {
>  int get_rate(unsigned *rate, const char *str)
>  {
>  	char *p;
> -	double bps = strtod(str, &p);
> +	long long bps = strtoll(str, &p, 0);

Oops, I read this as being strtol() currently, not strtod().  Currently
'1.5gbit' will work, but this change will break that.  So I think you
need to keep bps as a double.

>  	const struct rate_suffix *s;
>  
>  	if (p == str)
>  		return -1;
>  
> -	if (*p == '\0') {
> -		*rate = bps / 8.;	/* assume bits/sec */
> -		return 0;
> -	}
> -
>  	for (s = suffixes; s->name; ++s) {
>  		if (strcasecmp(s->name, p) == 0) {
> -			*rate = (bps * s->scale) / 8.;
> -			return 0;
> +			bps *= s->scale;
> +			p += strlen(p);
> +			break;
>  		}
>  	}
>  
> -	return -1;
> +	if (*p)
> +		return -1; /* unknown suffix */
> +	bps /= 8; /* -> bytes per second */
> +	*rate = bps;
> +	/* detect if an overflow happened */
> +	if (*rate != bps)

Then here I think the check should be *rate != floor(bps), i.e. accept
rounding down of a non-integer number of bytes but any other change is
assumed to be overflow.

Ben.

> +		return -1;
> +	return 0;
>  }
>  
>  void print_rate(char *buf, int len, __u32 rate)
> 
> 

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 iproute2] get_rate: detect 32bit overflows
  2013-06-03 15:36       ` Ben Hutchings
@ 2013-06-03 15:51         ` Eric Dumazet
  2013-06-03 16:31           ` Ben Hutchings
  0 siblings, 1 reply; 9+ messages in thread
From: Eric Dumazet @ 2013-06-03 15:51 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: Stephen Hemminger, netdev

On Mon, 2013-06-03 at 16:36 +0100, Ben Hutchings wrote:

> Oops, I read this as being strtol() currently, not strtod().  Currently
> '1.5gbit' will work, but this change will break that.  So I think you
> need to keep bps as a double.

Arg

> Then here I think the check should be *rate != floor(bps), i.e. accept
> rounding down of a non-integer number of bytes but any other change is
> assumed to be overflow.

Thanks Ben, here is v4 then ;)

[PATCH v4] get_rate: detect 32bit overflows

Current rate limit is 34.359.738.360 bit per second, and
unfortunately 40Gbps links are above it.

overflows in get_rate() are currently not detected, and some
users are confused. Let's detect this and complain.

Note that some qdisc are ready to get extended range, but this will
need additional attributes and new iproute2

With help from Ben Hutchings

Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 tc/tc_util.c |   20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/tc/tc_util.c b/tc/tc_util.c
index 8e62a01..8114c97 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -152,19 +152,23 @@ int get_rate(unsigned *rate, const char *str)
 	if (p == str)
 		return -1;
 
-	if (*p == '\0') {
-		*rate = bps / 8.;	/* assume bits/sec */
-		return 0;
-	}
-
 	for (s = suffixes; s->name; ++s) {
 		if (strcasecmp(s->name, p) == 0) {
-			*rate = (bps * s->scale) / 8.;
-			return 0;
+			bps *= s->scale;
+			p += strlen(p);
+			break;
 		}
 	}
 
-	return -1;
+	if (*p)
+		return -1; /* unknown suffix */
+
+	bps /= 8; /* -> bytes per second */
+	*rate = bps;
+	/* detect if an overflow happened */
+	if (*rate != floor(bps))
+		return -1;
+	return 0;
 }
 
 void print_rate(char *buf, int len, __u32 rate)

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 iproute2] get_rate: detect 32bit overflows
  2013-06-03 15:51         ` Eric Dumazet
@ 2013-06-03 16:31           ` Ben Hutchings
  0 siblings, 0 replies; 9+ messages in thread
From: Ben Hutchings @ 2013-06-03 16:31 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Stephen Hemminger, netdev

On Mon, 2013-06-03 at 08:51 -0700, Eric Dumazet wrote:
> On Mon, 2013-06-03 at 16:36 +0100, Ben Hutchings wrote:
> 
> > Oops, I read this as being strtol() currently, not strtod().  Currently
> > '1.5gbit' will work, but this change will break that.  So I think you
> > need to keep bps as a double.
> 
> Arg
> 
> > Then here I think the check should be *rate != floor(bps), i.e. accept
> > rounding down of a non-integer number of bytes but any other change is
> > assumed to be overflow.
> 
> Thanks Ben, here is v4 then ;)
> 
> [PATCH v4] get_rate: detect 32bit overflows
> 
> Current rate limit is 34.359.738.360 bit per second, and
> unfortunately 40Gbps links are above it.
> 
> overflows in get_rate() are currently not detected, and some
> users are confused. Let's detect this and complain.
> 
> Note that some qdisc are ready to get extended range, but this will
> need additional attributes and new iproute2
> 
> With help from Ben Hutchings
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>
[...]

Reviewed-by: Ben Hutchings <bhutchings@solarflare.com>

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 iproute2] get_rate: detect 32bit overflows
  2013-06-02 21:36 ` [PATCH v2 " Eric Dumazet
  2013-06-03 14:37   ` Ben Hutchings
@ 2013-06-07 16:25   ` Stephen Hemminger
  1 sibling, 0 replies; 9+ messages in thread
From: Stephen Hemminger @ 2013-06-07 16:25 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev

On Sun, 02 Jun 2013 14:36:48 -0700
Eric Dumazet <eric.dumazet@gmail.com> wrote:

> Current rate limit is 34.359.738.360 bit per second, and
> unfortunately 40Gbps links are above it.
> 
> overflows in get_rate() are currently not detected, and some
> users are confused. Let's detect this and complain.
> 
> Note that some qdisc are ready to get extended range, but this will
> need additional attributes and new iproute2
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Applied

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2013-06-07 16:25 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-02 18:51 [PATCH iproute2] get_rate: detect 32bit overflows Eric Dumazet
2013-06-02 21:30 ` Eric Dumazet
2013-06-02 21:36 ` [PATCH v2 " Eric Dumazet
2013-06-03 14:37   ` Ben Hutchings
2013-06-03 15:19     ` Eric Dumazet
2013-06-03 15:36       ` Ben Hutchings
2013-06-03 15:51         ` Eric Dumazet
2013-06-03 16:31           ` Ben Hutchings
2013-06-07 16:25   ` Stephen Hemminger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).