Handling MED value

Ondrej Zajicek santiago at crfreenet.org
Thu Dec 15 11:12:55 CET 2011


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 at 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."
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
URL: <http://trubka.network.cz/pipermail/bird-users/attachments/20111215/1421d4ef/attachment-0001.asc>


More information about the Bird-users mailing list