Hi Ondrej, As you may know MED value of BGP protocol field has 2 octets, so it can be 0 through 4294967295. On the other hand, bird defines the data type of MED as "int" and it limits the value between -2000000000 and 2000000000 according to bird doc. So, It doesn't seems to able to handle to compare MED value (or add/subtract them) in function correnctly. I tried a workaround below, but it fails to load bird.conf with a syntax error message. bird> configure Reading configuration from /etc/bird.conf /etc/bird.conf, line 123: Number out of range 120:function TEST() 121:{ 122: if (source = RTS_BGP) then { 123: if (bgp_med + 100 < 4294967295) then { 124: bgp_med = bgp_med + 100; 125: } else { 126: bgp_med = 4294967295; 127: } 128:} This function means boundary check: When the MED value received + 100 is lower than 4294967295, it just updates MED. Otherwise, it sets 4294967295. Cisco IOS does. And the following commands instead of using the above function shows the MED value overflowed. bird> show route table master all 192.168.0.0/24 via 172.16.0.1 on eth0 [TEST 2011-12-13 14:39:30] * (100) [AS65000i] Type: BGP unicast univ BGP.origin: IGP BGP.as_path: 65000 BGP.next_hop: 172.16.0.1 BGP.med: 4294967294 BGP.local_pref: 100 bird> show route table master filter { if source = RTS_BGP then {bgp_med = bgp_med + 100; accept;}} all 192.168.0.0/24 via 172.16.0.1 on eth0 [TEST 2011-12-13 14:39:30] * (100) [AS65000i] Type: BGP unicast univ BGP.origin: IGP BGP.as_path: 65000 BGP.next_hop: 172.16.0.1 BGP.med: 98 <= *This* BGP.local_pref: 100 bird> We want a new data type which has the integer value between 0 and 4294967295 such as unsingned int (32bit) in C. What do you think? Thanks, Eiichiro -- ################################################### Eiichiro Watanabe Internet Multifeed Co.
On Tue, Dec 13, 2011 at 03:15:12PM +0900, Eiichiro Watanabe wrote:
Hi Ondrej,
As you may know MED value of BGP protocol field has 2 octets, so it can be 0 through 4294967295. On the other hand, bird defines the data type of MED as "int" and it limits the value between -2000000000 and 2000000000 according to bird doc.
So, It doesn't seems to able to handle to compare MED value (or add/subtract them) in function correnctly.
The documentation is inexact in this matter and the issue of signedness of the basic numerical BIRD type 'int' is unclear - numerical constants have unsigned range (0..4294967295), we don't even have a negative constants, but operations work like signed. Some operations (+, -) works exactly same on signed and unsigned, so there is not a problem with adding/substracting, some operations (*, /) are uncommon, so probably the only practical differenence is in the comparison, where numbers larger than 2147483647 are treated as negative. But it seems that your problem is not exactly with signedness, but with overflow (instead of saturation). Overflow works also the same for signed and unsigned ones. I thought about this some time ago and probably the best solution would be to switch BIRD completely to unsigned behavior (as most route properties with 32bit ranage are defined as unsigned) in some major release.
I tried a workaround below, but it fails to load bird.conf with a syntax error message.
bird> configure Reading configuration from /etc/bird.conf /etc/bird.conf, line 123: Number out of range
What version of BIRD do you use? In the current version, it loads just fine (when i fixed missing '}'). But the code does not do what you expect, even if the numeric operations (comparison) would be unsigned 32bit - in that case the condition 'bgp_med + 100 < 4294967295' would be always satisfied. You can write the function like this: function TEST() int n; { if (source = RTS_BGP) then { n = bgp_med + 100; if (n >= 0 && n < 100) then bgp_med = n; else bgp_med = 4294967295; }
And the following commands instead of using the above function shows the MED value overflowed. bird> show route table master all ... BGP.med: 4294967294 ... bird> show route table master filter { if source = RTS_BGP then {bgp_med = bgp_med + 100; accept;}} all ... BGP.med: 98 <= *This* bird>
This is exactly the same how unsigned int (32bit) works in C. -- Elen sila lumenn' omentielvo Ondrej 'SanTiago' Zajicek (email: santiago@crfreenet.org) OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net) "To err is human -- to blame it on a computer is even more so."
Hello!
But it seems that your problem is not exactly with signedness, but with overflow (instead of saturation). Overflow works also the same for signed and unsigned ones.
I thought about this some time ago and probably the best solution would be to switch BIRD completely to unsigned behavior (as most route properties with 32bit ranage are defined as unsigned) in some major release.
While I think that switching to unsigned is a good idea, I am not sure that silent overflows make sense. Maybe we should log the overflows or use saturation arithmetics instead. Have a nice fortnight -- Martin `MJ' Mares <mj@ucw.cz> http://mj.ucw.cz/ Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth int*(*maso(int*(*p1)(void),int*(*p2)(void)))(void); -- F. Zavoral
On Thu, Dec 15, 2011 at 11:30:04AM +0100, Martin Mares wrote:
Hello!
But it seems that your problem is not exactly with signedness, but with overflow (instead of saturation). Overflow works also the same for signed and unsigned ones.
I thought about this some time ago and probably the best solution would be to switch BIRD completely to unsigned behavior (as most route properties with 32bit ranage are defined as unsigned) in some major release.
While I think that switching to unsigned is a good idea, I am not sure that silent overflows make sense. Maybe we should log the overflows or use saturation arithmetics instead.
You are probably right about silent overflows. I would prefer logging them because silent saturation may be unexpected to many users as well. -- Elen sila lumenn' omentielvo Ondrej 'SanTiago' Zajicek (email: santiago@crfreenet.org) OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net) "To err is human -- to blame it on a computer is even more so."
On Thu, 15 Dec 2011, Ondrej Zajicek wrote:
On Thu, Dec 15, 2011 at 11:30:04AM +0100, Martin Mares wrote:
But it seems that your problem is not exactly with signedness, but with overflow (instead of saturation). Overflow works also the same for signed and unsigned ones.
I thought about this some time ago and probably the best solution would be to switch BIRD completely to unsigned behavior (as most route properties with 32bit ranage are defined as unsigned) in some major release.
While I think that switching to unsigned is a good idea, I am not sure that silent overflows make sense. Maybe we should log the overflows or use saturation arithmetics instead.
You are probably right about silent overflows. I would prefer logging them because silent saturation may be unexpected to many users as well.
It is less surprising than the warp-around caused by unsaturated overflows, so it is probably best to do both: saturate and log. -- "One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie." -- The Silicon Valley Tarot Henrique Holschuh
But it seems that your problem is not exactly with signedness, but with overflow (instead of saturation). Overflow works also the same for signed and unsigned ones.
I thought about this some time ago and probably the best solution would be to switch BIRD completely to unsigned behavior (as most route properties with 32bit ranage are defined as unsigned) in some major release.
It's good idea.
I tried a workaround below, but it fails to load bird.conf with a syntax error message.
bird> configure Reading configuration from /etc/bird.conf /etc/bird.conf, line 123: Number out of range
What version of BIRD do you use? In the current version, it loads just fine (when i fixed missing '}'). But the code does not do what you expect, even if the numeric operations (comparison) would be unsigned 32bit - in that case the condition 'bgp_med + 100< 4294967295' would be always satisfied.
I am using 1.3.4 on Debian/GNU Linux(64bit).
You can write the function like this:
function TEST() int n; { if (source = RTS_BGP) then { n = bgp_med + 100; if (n>= 0&& n< 100) then bgp_med = n; else bgp_med = 4294967295; }
uum..., It's strange. That fails on my environment. "bgp_med = 4294967295;" statement in line 93 also looks to fail. bird> configure Reading configuration from /etc/bird.conf /etc/bird.conf, line 93: Number out of range However, I've realized this as a workaround. function TEST() int n; { if (source = RTS_BGP ) then { if defined(bgp_med) then { n = bgp_med + 100; if (n >= 0 && n < 100) then bgp_med = 0 - 1; else bgp_med = n; } else { bgp_med = 100; } } return true; } Any comments? Thanks, Eiichiro -- ################################################### Eiichiro Watanabe Internet Multifeed Co.
On Mon, Dec 19, 2011 at 10:19:49AM +0900, Eiichiro Watanabe wrote:
You can write the function like this:
function TEST() int n; { if (source = RTS_BGP) then { n = bgp_med + 100; if (n>= 0&& n< 100) then bgp_med = n; else bgp_med = 4294967295; }
uum..., It's strange. That fails on my environment. "bgp_med = 4294967295;" statement in line 93 also looks to fail.
I checked that and it fails in 64bit environment. You can use attached code to fix it. -- Elen sila lumenn' omentielvo Ondrej 'SanTiago' Zajicek (email: santiago@crfreenet.org) OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net) "To err is human -- to blame it on a computer is even more so."
Hi Ondrej, It worked on my environment. Thank you! Eiichiro Ondrej Zajicek wrote (2011/12/22 21:46):
On Mon, Dec 19, 2011 at 10:19:49AM +0900, Eiichiro Watanabe wrote:
You can write the function like this:
function TEST() int n; { if (source = RTS_BGP) then { n = bgp_med + 100; if (n>= 0&& n< 100) then bgp_med = n; else bgp_med = 4294967295; }
uum..., It's strange. That fails on my environment. "bgp_med = 4294967295;" statement in line 93 also looks to fail.
I checked that and it fails in 64bit environment. You can use attached code to fix it.
-- ################################################### Eiichiro Watanabe Internet Multifeed Co.
participants (4)
-
Eiichiro Watanabe -
Henrique de Moraes Holschuh -
Martin Mares -
Ondrej Zajicek