When userspace use RTM_GETROUTE to dump route table, with a already
expired route entry, we always got an 'expires' value(2147157)
calculated base on INT_MAX.
The reason of this problem is in the following satement:
rt->dst.expires - jiffies < INT_MAX
gcc promoted the type of both sides of '<' to unsigned long, thus
a small negative value would be considered greater than INT_MAX.
This patch fix this by cast the result of subtraction to an 'int'
which I think is large enough for the expires.
Also we should do some fix in rtnl_put_cacheinfo() which use
jiffies_to_clock_t(which take an unsigned log as parameter) to
convert jiffies to clock_t to handle the negative expires.
---
net/core/rtnetlink.c | 3 ++-
net/ipv6/route.c | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
@@ -2516,7 +2516,7 @@ static int rt6_fill_node(struct net *net,gotonla_put_failure;if(!(rt->rt6i_flags&RTF_EXPIRES))expires=0;-elseif(rt->dst.expires-jiffies<INT_MAX)+elseif((int)(rt->dst.expires-jiffies)<INT_MAX)expires=rt->dst.expires-jiffies;elseexpires=INT_MAX;
@@ -2516,7 +2516,7 @@ static int rt6_fill_node(struct net *net,gotonla_put_failure;if(!(rt->rt6i_flags&RTF_EXPIRES))expires=0;-elseif(rt->dst.expires-jiffies<INT_MAX)+elseif((int)(rt->dst.expires-jiffies)<INT_MAX)expires=rt->dst.expires-jiffies;elseexpires=INT_MAX;
@@ -2516,7 +2516,7 @@ static int rt6_fill_node(struct net *net,gotonla_put_failure;if(!(rt->rt6i_flags&RTF_EXPIRES))expires=0;-elseif(rt->dst.expires-jiffies<INT_MAX)+elseif((int)(rt->dst.expires-jiffies)<INT_MAX)expires=rt->dst.expires-jiffies;elseexpires=INT_MAX;
Why not use time_is_after_jiffies() macro?
time_is_after_jiffies() return a bool but we need "how much time
before/after jiffies" here.
However, I also think these code seems a little ugly, because we
need to store the result of two "unsigned long"'s subtraction into
an integer. Maybe we should distinguish expires before and after
jiffies to proper process the overflows.
Thanks,
Wei
@@ -2516,7 +2516,7 @@ static int rt6_fill_node(struct net *net,gotonla_put_failure;if(!(rt->rt6i_flags&RTF_EXPIRES))expires=0;-elseif(rt->dst.expires-jiffies<INT_MAX)+elseif((int)(rt->dst.expires-jiffies)<INT_MAX)expires=rt->dst.expires-jiffies;elseexpires=INT_MAX;
When userspace use RTM_GETROUTE to dump route table, with an already
expired route entry, we always got an 'expires' value(2147157)
calculated base on INT_MAX.
The reason of this problem is in the following satement:
rt->dst.expires - jiffies < INT_MAX
gcc promoted the type of both sides of '<' to unsigned long, thus
a small negative value would be considered greater than INT_MAX.
This patch fix this by use the same trick as time_after macro to
avoid the 'unsigned long' type promotion and deal with jiffies
wrapping.
Also we should do some fix in rtnl_put_cacheinfo() which use
jiffies_to_clock_t(which take an unsigned long as parameter) to
convert jiffies to clock_t to handle the negative expires.
Signed-off-by: Li Wei <redacted>
---
net/core/rtnetlink.c | 3 ++-
net/ipv6/route.c | 8 +++++---
2 files changed, 7 insertions(+), 4 deletions(-)
@@ -2516,10 +2516,12 @@ static int rt6_fill_node(struct net *net,gotonla_put_failure;if(!(rt->rt6i_flags&RTF_EXPIRES))expires=0;-elseif(rt->dst.expires-jiffies<INT_MAX)-expires=rt->dst.expires-jiffies;+elseif((long)rt->dst.expires-(long)jiffies>INT_MIN+&&(long)rt->dst.expires-(long)jiffies<INT_MAX)+expires=(long)rt->dst.expires-(long)jiffies;else-expires=INT_MAX;+expires=time_is_after_jiffies(rt->dst.expires)?INT_MAX:INT_MIN;peer=rt->rt6i_peer;ts=tsage=0;
When userspace use RTM_GETROUTE to dump route table, with an already
expired route entry, we always got an 'expires' value(2147157)
calculated base on INT_MAX.
The reason of this problem is in the following satement:
rt->dst.expires - jiffies < INT_MAX
gcc promoted the type of both sides of '<' to unsigned long, thus
a small negative value would be considered greater than INT_MAX.
This patch fix this by use the same trick as time_after macro to
avoid the 'unsigned long' type promotion and deal with jiffies
wrapping.
Also we should do some fix in rtnl_put_cacheinfo() which use
jiffies_to_clock_t(which take an unsigned long as parameter) to
convert jiffies to clock_t to handle the negative expires.
Signed-off-by: Li Wei <redacted>
Your patch is corrupted by your email client and therefore will
not apply cleanly.
I think this isn't the first time your patch submissions have
had this problem, and if so then you should do the necessary
work to prevent problem with more certainty in the future as
such this makes a lot of extra work for other people.
When userspace use RTM_GETROUTE to dump route table, with an already
expired route entry, we always got an 'expires' value(2147157)
calculated base on INT_MAX.
The reason of this problem is in the following satement:
rt->dst.expires - jiffies < INT_MAX
gcc promoted the type of both sides of '<' to unsigned long, thus
a small negative value would be considered greater than INT_MAX.
This patch fix this by use the same trick as time_after macro to
avoid the 'unsigned long' type promotion and deal with jiffies
wrapping.
Also we should do some fix in rtnl_put_cacheinfo() which use
jiffies_to_clock_t(which take an unsigned long as parameter) to
convert jiffies to clock_t to handle the negative expires.
Signed-off-by: Li Wei <redacted>
Your patch is corrupted by your email client and therefore will
not apply cleanly.
I think this isn't the first time your patch submissions have
had this problem, and if so then you should do the necessary
work to prevent problem with more certainty in the future as
such this makes a lot of extra work for other people.
Really sorry for that, I'll resend this patch and before that sending
myself a copy to confirm the mail client works properly.
Thanks
When userspace use RTM_GETROUTE to dump route table, with an already
expired route entry, we always got an 'expires' value(2147157)
calculated base on INT_MAX.
The reason of this problem is in the following satement:
rt->dst.expires - jiffies < INT_MAX
gcc promoted the type of both sides of '<' to unsigned long, thus
a small negative value would be considered greater than INT_MAX.
This patch fix this by use the same trick as time_after macro to
avoid the 'unsigned long' type promotion and deal with jiffies
wrapping.
Also we should do some fix in rtnl_put_cacheinfo() which use
jiffies_to_clock_t(which take an unsigned long as parameter) to
convert jiffies to clock_t to handle the negative expires.
Signed-off-by: Li Wei <redacted>
---
net/core/rtnetlink.c | 3 ++-
net/ipv6/route.c | 7 ++++---
2 files changed, 6 insertions(+), 4 deletions(-)
@@ -2516,10 +2516,11 @@ static int rt6_fill_node(struct net *net,gotonla_put_failure;if(!(rt->rt6i_flags&RTF_EXPIRES))expires=0;-elseif(rt->dst.expires-jiffies<INT_MAX)-expires=rt->dst.expires-jiffies;+elseif((long)rt->dst.expires-(long)jiffies>INT_MIN+&&(long)rt->dst.expires-(long)jiffies<INT_MAX)+expires=(long)rt->dst.expires-(long)jiffies;else-expires=INT_MAX;+expires=time_is_after_jiffies(rt->dst.expires)?INT_MAX:INT_MIN;peer=rt->rt6i_peer;ts=tsage=0;
INT_MAX : INT_MIN;
I can't help feeling there is a better way to do this.
Maybe:
long expires = rt->dst.expires - jiffies;
if (expires != (int)expires)
expires = expires > 0 ? INT_MAX : INT_MIN;
Although maybe -INT_MAX instead of INT_MIN.
David
INT_MAX : INT_MIN;
I can't help feeling there is a better way to do this.
Maybe:
long expires = rt->dst.expires - jiffies;
if (expires != (int)expires)
expires = expires > 0 ? INT_MAX : INT_MIN;
Although maybe -INT_MAX instead of INT_MIN.
This patch also does not apply at all to net-next, so needs to be
redone regardless.
INT_MAX : INT_MIN;
I can't help feeling there is a better way to do this.
Maybe:
long expires = rt->dst.expires - jiffies;
if (expires != (int)expires)
expires = expires > 0 ? INT_MAX : INT_MIN;
Although maybe -INT_MAX instead of INT_MIN.
David
Thanks David, your code looks much cleaner and can archieve the same
function except we should use
long expires = (long)rt->dst.expires - (long)jiffies;
to avoid the wrapping of jiffies.
Thanks,
Wei
INT_MAX : INT_MIN;
I can't help feeling there is a better way to do this.
Maybe:
long expires = rt->dst.expires - jiffies;
if (expires != (int)expires)
expires = expires > 0 ? INT_MAX : INT_MIN;
Although maybe -INT_MAX instead of INT_MIN.
This patch also does not apply at all to net-next, so needs to be
redone regardless.
When userspace use RTM_GETROUTE to dump route table, with an already
expired route entry, we always got an 'expires' value(2147157)
calculated base on INT_MAX.
The reason of this problem is in the following satement:
rt->dst.expires - jiffies < INT_MAX
gcc promoted the type of both sides of '<' to unsigned long, thus
a small negative value would be considered greater than INT_MAX.
This patch fix this by use the same trick as time_after macro to
avoid the 'unsigned long' type promotion and deal with jiffies
wrapping.
Also we should do some fix in rtnl_put_cacheinfo() which use
jiffies_to_clock_t(which take an unsigned long as parameter) to
convert jiffies to clock_t to handle the negative expires.
With the help of David Laight, we can make the code a little clean.
Signed-off-by: Li Wei <redacted>
---
net/core/rtnetlink.c | 3 ++-
net/ipv6/route.c | 11 ++++++-----
2 files changed, 8 insertions(+), 6 deletions(-)
@@ -2480,12 +2480,13 @@ static int rt6_fill_node(struct net *net,gotonla_put_failure;if(nla_put_u32(skb,RTA_PRIORITY,rt->rt6i_metric))gotonla_put_failure;-if(!(rt->rt6i_flags&RTF_EXPIRES))+if(!(rt->rt6i_flags&RTF_EXPIRES)){expires=0;-elseif(rt->dst.expires-jiffies<INT_MAX)-expires=rt->dst.expires-jiffies;-else-expires=INT_MAX;+}else{+expires=(long)rt->dst.expires-(long)jiffies;+if(expires!=(int)expires)+expires=expires>0?INT_MAX:INT_MIN;+}if(rtnl_put_cacheinfo(skb,&rt->dst,0,expires,rt->dst.error)<0)gotonla_put_failure;
From: Eric Dumazet <hidden> Date: 2012-07-25 06:52:00
On Wed, 2012-07-25 at 13:25 +0800, Li Wei wrote:
quoted hunk
When userspace use RTM_GETROUTE to dump route table, with an already
expired route entry, we always got an 'expires' value(2147157)
calculated base on INT_MAX.
The reason of this problem is in the following satement:
rt->dst.expires - jiffies < INT_MAX
gcc promoted the type of both sides of '<' to unsigned long, thus
a small negative value would be considered greater than INT_MAX.
This patch fix this by use the same trick as time_after macro to
avoid the 'unsigned long' type promotion and deal with jiffies
wrapping.
Also we should do some fix in rtnl_put_cacheinfo() which use
jiffies_to_clock_t(which take an unsigned long as parameter) to
convert jiffies to clock_t to handle the negative expires.
With the help of David Laight, we can make the code a little clean.
Signed-off-by: Li Wei <redacted>
---
net/core/rtnetlink.c | 3 ++-
net/ipv6/route.c | 11 ++++++-----
2 files changed, 8 insertions(+), 6 deletions(-)
@@ -2480,12 +2480,13 @@ static int rt6_fill_node(struct net *net,gotonla_put_failure;if(nla_put_u32(skb,RTA_PRIORITY,rt->rt6i_metric))gotonla_put_failure;-if(!(rt->rt6i_flags&RTF_EXPIRES))+if(!(rt->rt6i_flags&RTF_EXPIRES)){expires=0;-elseif(rt->dst.expires-jiffies<INT_MAX)-expires=rt->dst.expires-jiffies;-else-expires=INT_MAX;+}else{+expires=(long)rt->dst.expires-(long)jiffies;+if(expires!=(int)expires)+expires=expires>0?INT_MAX:INT_MIN;+}if(rtnl_put_cacheinfo(skb,&rt->dst,0,expires,rt->dst.error)<0)gotonla_put_failure;
All this sounds not very clean.
rtnl_put_cacheinfo( ... long expires ... )
Any out of bound checks should be done in rtnl_put_cacheinfo(), _after_
conversion to clock_t.
@@ -2480,12 +2480,8 @@ static int rt6_fill_node(struct net *net,gotonla_put_failure;if(nla_put_u32(skb,RTA_PRIORITY,rt->rt6i_metric))gotonla_put_failure;-if(!(rt->rt6i_flags&RTF_EXPIRES))-expires=0;-elseif(rt->dst.expires-jiffies<INT_MAX)-expires=rt->dst.expires-jiffies;-else-expires=INT_MAX;++expires=(rt->rt6i_flags&RTF_EXPIRES)?rt->dst.expires-jiffies:0;if(rtnl_put_cacheinfo(skb,&rt->dst,0,expires,rt->dst.error)<0)gotonla_put_failure;
When userspace use RTM_GETROUTE to dump route table, with an already
expired route entry, we always got an 'expires' value(2147157)
calculated base on INT_MAX.
The reason of this problem is in the following satement:
rt->dst.expires - jiffies < INT_MAX
gcc promoted the type of both sides of '<' to unsigned long, thus
a small negative value would be considered greater than INT_MAX.
This patch fix this by use the same trick as time_after macro to
avoid the 'unsigned long' type promotion and deal with jiffies
wrapping.
Also we should do some fix in rtnl_put_cacheinfo() which use
jiffies_to_clock_t(which take an unsigned long as parameter) to
convert jiffies to clock_t to handle the negative expires.
With the help of David Laight, we can make the code a little clean.
Signed-off-by: Li Wei <redacted>
---
net/core/rtnetlink.c | 3 ++-
net/ipv6/route.c | 11 ++++++-----
2 files changed, 8 insertions(+), 6 deletions(-)
@@ -2480,12 +2480,13 @@ static int rt6_fill_node(struct net *net,gotonla_put_failure;if(nla_put_u32(skb,RTA_PRIORITY,rt->rt6i_metric))gotonla_put_failure;-if(!(rt->rt6i_flags&RTF_EXPIRES))+if(!(rt->rt6i_flags&RTF_EXPIRES)){expires=0;-elseif(rt->dst.expires-jiffies<INT_MAX)-expires=rt->dst.expires-jiffies;-else-expires=INT_MAX;+}else{+expires=(long)rt->dst.expires-(long)jiffies;+if(expires!=(int)expires)+expires=expires>0?INT_MAX:INT_MIN;+}if(rtnl_put_cacheinfo(skb,&rt->dst,0,expires,rt->dst.error)<0)gotonla_put_failure;
All this sounds not very clean.
rtnl_put_cacheinfo( ... long expires ... )
Any out of bound checks should be done in rtnl_put_cacheinfo(), _after_
conversion to clock_t.
Ok, I got it.
I tested the following patch, got the correct expires value and not found
any problem.
Thanks Eric :)
@@ -2480,12 +2480,8 @@ static int rt6_fill_node(struct net *net,gotonla_put_failure;if(nla_put_u32(skb,RTA_PRIORITY,rt->rt6i_metric))gotonla_put_failure;-if(!(rt->rt6i_flags&RTF_EXPIRES))-expires=0;-elseif(rt->dst.expires-jiffies<INT_MAX)-expires=rt->dst.expires-jiffies;-else-expires=INT_MAX;++expires=(rt->rt6i_flags&RTF_EXPIRES)?rt->dst.expires-jiffies:0;if(rtnl_put_cacheinfo(skb,&rt->dst,0,expires,rt->dst.error)<0)gotonla_put_failure;
When userspace use RTM_GETROUTE to dump route table, with an already
expired route entry, we always got an 'expires' value(2147157)
calculated base on INT_MAX.
The reason of this problem is in the following satement:
rt->dst.expires - jiffies < INT_MAX
gcc promoted the type of both sides of '<' to unsigned long, thus
a small negative value would be considered greater than INT_MAX.
With the help of Eric Dumazet, do the out of bound checks in
rtnl_put_cacheinfo(), _after_ conversion to clock_t.
Signed-off-by: Li Wei <redacted>
---
In fact, all the code was reconstructed by Eric, I just put the
commit log and resent it to the maillist, thanks Eric!
net/core/rtnetlink.c | 8 ++++++--
net/ipv6/route.c | 8 ++------
2 files changed, 8 insertions(+), 8 deletions(-)
@@ -2480,12 +2480,8 @@ static int rt6_fill_node(struct net *net,gotonla_put_failure;if(nla_put_u32(skb,RTA_PRIORITY,rt->rt6i_metric))gotonla_put_failure;-if(!(rt->rt6i_flags&RTF_EXPIRES))-expires=0;-elseif(rt->dst.expires-jiffies<INT_MAX)-expires=rt->dst.expires-jiffies;-else-expires=INT_MAX;++expires=(rt->rt6i_flags&RTF_EXPIRES)?rt->dst.expires-jiffies:0;if(rtnl_put_cacheinfo(skb,&rt->dst,0,expires,rt->dst.error)<0)gotonla_put_failure;
When userspace use RTM_GETROUTE to dump route table, with an already
expired route entry, we always got an 'expires' value(2147157)
calculated base on INT_MAX.
The reason of this problem is in the following satement:
rt->dst.expires - jiffies < INT_MAX
gcc promoted the type of both sides of '<' to unsigned long, thus
a small negative value would be considered greater than INT_MAX.
With the help of Eric Dumazet, do the out of bound checks in
rtnl_put_cacheinfo(), _after_ conversion to clock_t.
Signed-off-by: Li Wei <redacted>