Commit cc5b93f7 authored by Ondřej Zajíček's avatar Ondřej Zajíček

Merge tag 'v1.6.2' into int-new

parents 5de0e848 f51b1f55
/autom4te.cache/
/doc/*.html
/obj/
/Makefile
/bird
/birdc
/birdcl
/config.log
/config.status
/configure
/bird.conf
/bird.log
Version 1.6.2 (2016-09-29)
o Fixes serious bug introduced in the previous version
Version 1.6.1 (2016-09-22)
o Support for IPv6 ECMP
o Better handling of IPv6 tentative addresses
o Several updates and fixes in Babel protocol
o Filter: New !~ operator
o Filter: ASN ranges in bgpmask
o KRT: New kernel protocol option 'metric'
o KRT: New route attribute 'krt_scope'
o Improved BIRD help messages
o Fixes memory leak in BGP multipath
o Fixes handling of empty path segments in BGP AS_PATH
o Several bug fixes
Version 1.6.0 (2016-04-29)
o Major RIP protocol redesign
o New Babel routing protocol
......
BIRD Internet Routing Daemon
BIRD Internet Routing Daemon
(c) 1998--2008 Martin Mares <mj@ucw.cz>
Home page http://bird.network.cz/
Mailing list bird-users@network.cz
(c) 1998--2008 Martin Mares <mj@ucw.cz>
(c) 1998--2000 Pavel Machek <pavel@ucw.cz>
(c) 1998--2008 Ondrej Filip <feela@network.cz>
(c) 2009--2013 CZ.NIC z.s.p.o.
(c) 2009--2016 CZ.NIC z.s.p.o.
================================================================================
The BIRD project is an attempt to create a routing daemon running on UNIX-like
systems (but not necessarily limited to them) with full support of all modern
routing protocols, easy to use configuration interface and powerful route
filtering language.
If you want to help us debugging, enhancing and porting BIRD or just lurk
around to see what's going to develop from this strange creature, feel free
to subscribe to the BIRD users mailing list (bird-users@bird.network.cz),
send subscribes to majordomo at the same machine). Bug reports, suggestions,
feature requests (: and code :) are welcome.
The BIRD project aims to develop a dynamic IP routing daemon with full support
of all modern routing protocols, easy to use configuration interface and
powerful route filtering language, primarily targeted on (but not limited to)
Linux and other UNIX-like systems and distributed under the GNU General
Public License.
You can download the latest version from ftp://bird.network.cz/pub/bird/
and look at the BIRD home page at http://bird.network.cz/.
What do we support
==================
BIRD development started as a student project at the Faculty of Math
and Physics, Charles University, Prague, Czech Republic under supervision
of RNDr. Libor Forst <forst@cuni.cz>. BIRD has been developed and supported
by CZ.NIC z.s.p.o. http://www.nic.cz/ since 2009.
o Both IPv4 and IPv6 (use --enable-ipv6 when configuring)
o Multiple routing tables
o Border Gateway Protocol (BGPv4)
o Routing Information Protocol (RIPv2, RIPng)
o Open Shortest Path First protocol (OSPFv2, OSPFv3)
o Babel Routing Protocol (Babel)
o Bidirectional Forwarding Detection (BFD)
o IPv6 router advertisements
o Static routes
o Inter-table protocol
o Command-line interface allowing on-line control and inspection of
status of the daemon
o Soft reconfiguration, no need to use complex online commands to
change the configuration, just edit the configuration file and notify
BIRD to re-read it and it will smoothly switch itself to the new
configuration, not disturbing routing protocols unless they are
affected by the configuration changes
o Powerful language for route filtering, see doc/bird.conf.example
o Linux, FreeBSD, NetBSD and OpenBSD ports
How to install BIRD
===================
o From standard distribution package of your OS (recommended)
o From official binary packages for Debian and Red Hat Linux
ftp://bird.network.cz/pub/bird/debian/
ftp://bird.network.cz/pub/bird/redhat/
o From source code of the latest stable release version
ftp://bird.network.cz/pub/bird/
o From source code of the actual development version
git://git.nic.cz/bird.git
https://gitlab.labs.nic.cz/labs/bird/
How to install BIRD from source code
------------------------------------
$ ./configure
$ make
$ su
# make install
# vi /usr/local/etc/bird.conf
See the file INSTALL for more information about installation from source code.
Documentation
=============
Online documentation is available at http://bird.network.cz/?get_doc or as HTML
files in the doc directory, you can install it by `make install-docs' and
rebuild it by `make docs', but you'll need SGMLtools and LaTeX to be installed
on your machine. You can also download a neatly formatted PostScript version as
a separate archive (bird-doc-*.tar.gz) from ftp://bird.network.cz/pub/bird/
User support
============
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
If you want to help us debugging, enhancing and porting BIRD or just lurk
around to see what's going to develop, feel free to subscribe to the BIRD
users mailing list bird-users@network.cz, just send `subscribe' to
bird-request@network.cz. Bug reports, suggestions, feature requests and
code are welcome! We don't use gitlab issues for reporting, sorry.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Subscribe: http://bird.network.cz/mailman/listinfo/bird-users/
Archive: http://bird.network.cz/pipermail/bird-users/
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Licence
=======
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
How to install BIRD:
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
./configure
make
make install
vi /usr/local/etc/bird.conf
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Online documentation is available as HTML files in the doc directory,
you can install it by `make install-docs' and rebuild it by `make docs',
but for the latter you need SGMLtools and LaTeX to be installed on your
machine. You can also download a neatly formatted PostScript version
as a separate archive (bird-doc-*.tar.gz).
History
=======
What do we support:
BIRD development started as a student project at the Faculty of Math
and Physics, Charles University, Prague, Czech Republic under supervision
of RNDr. Libor Forst <forst@cuni.cz>. BIRD has been developed and supported
by CZ.NIC z.s.p.o. http://www.nic.cz/ since 2009.
o Both IPv4 and IPv6 (use --enable-ipv6 when configuring)
o Multiple routing tables
o BGP
o RIP
o OSPF
o Static routes
o Inter-table protocol
o IPv6 router advertisements
o Bidirectional Forwarding Detection (BFD)
o Command-line interface (using the `birdc' client; to get
some help, just press `?')
o Soft reconfiguration -- no online commands for changing the
configuration in very limited ways, just edit the configuration
file and issue a `configure' command or send SIGHUP and BIRD
will start using the new configuration, possibly restarting
protocols affected by the configuration changes.
o Powerful language for route filtering (see doc/bird.conf.example).
What is missing:
o See the TODO list
Good Luck and enjoy the BIRD :)
The BIRD Team
......@@ -40,6 +40,7 @@ bug(const char *msg, ...)
fputs("Internal error: ", stderr);
vlog(msg, args);
vfprintf(stderr, msg, args);
va_end(args);
exit(1);
}
......@@ -51,5 +52,6 @@ die(const char *msg, ...)
va_start(args, msg);
cleanup();
vlog(msg, args);
va_end(args);
exit(1);
}
......@@ -30,6 +30,7 @@
#include <errno.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include <unistd.h>
#include <libgen.h>
#include <glob.h>
......@@ -233,6 +234,7 @@ else: {
<CCOMM>.
\!\= return NEQ;
\!\~ return NMA;
\<\= return LEQ;
\>\= return GEQ;
\&\& return AND;
......
......@@ -512,6 +512,7 @@ cf_error(const char *msg, ...)
va_start(args, msg);
if (bvsnprintf(buf, sizeof(buf), msg, args) < 0)
strcpy(buf, "<bug: error message too long>");
va_end(args);
new_config->err_msg = cfg_strdup(buf);
new_config->err_lino = ifs->lino;
new_config->err_file_name = ifs->file_name;
......
......@@ -87,7 +87,7 @@ CF_DECLS
%nonassoc PREFIX_DUMMY
%left AND OR
%nonassoc '=' '<' '>' '~' GEQ LEQ NEQ PO PC
%nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA PO PC
%left '+' '-'
%left '*' '/' '%'
%left '!'
......
......@@ -610,8 +610,8 @@ agreement").
options, in that case for given interface the first matching interface
option is used.
This option is allowed in BFD, Direct, OSPF, RAdv and RIP protocols, but
in OSPF protocol it is used in the <cf/area/ subsection.
This option is allowed in Babel, BFD, Direct, OSPF, RAdv and RIP
protocols, but in OSPF protocol it is used in the <cf/area/ subsection.
Default: none.
......@@ -667,7 +667,7 @@ agreement").
<descrip>
<tag>id <M>num</M></tag>
ID of the password, (0-255). If it's not used, BIRD will choose ID based
ID of the password, (1-255). If it is not used, BIRD will choose ID based
on an order of the password item in the interface. For example, second
password item in one interface will have default ID 2. ID is used by
some routing protocols to identify which password was used to
......@@ -1016,9 +1016,9 @@ foot).
of type <cf/string/, print such variables, use standard string
comparison operations (e.g. <cf/=, !=, &lt;, &gt;, &lt;=, &gt;=/), but
you can't concatenate two strings. String literals are written as
<cf/"This is a string constant"/. Additionally matching <cf/&tilde;/
operator could be used to match a string value against a shell pattern
(represented also as a string).
<cf/"This is a string constant"/. Additionally matching (<cf/&tilde;,
!&tilde;/) operators could be used to match a string value against
a shell pattern (represented also as a string).
<tag/ip/
This type can hold a single IP address. Depending on the compile-time
......@@ -1035,7 +1035,7 @@ foot).
or <cf><m>ipaddress</m>/<m>netmask</m></cf>. There are two special
operators on prefixes: <cf/.ip/ which extracts the IP address from the
pair, and <cf/.len/, which separates prefix length from the pair.
So <cf>1.2.0.0/16.pxlen = 16</cf> is true.
So <cf>1.2.0.0/16.len = 16</cf> is true.
<tag/ec/
This is a specialized type used to represent BGP extended community
......@@ -1165,8 +1165,10 @@ foot).
is 4 3 2 1, then: <tt>bgp_path &tilde; [= * 4 3 * =]</tt> is true,
but <tt>bgp_path &tilde; [= * 4 5 * =]</tt> is false. BGP mask
expressions can also contain integer expressions enclosed in parenthesis
and integer variables, for example <tt>[= * 4 (1+2) a =]</tt>. There is
also old syntax that uses / .. / instead of [= .. =] and ? instead of *.
and integer variables, for example <tt>[= * 4 (1+2) a =]</tt>. You can
also use ranges, for example <tt>[= * 3..5 2 100..200 * =]</tt>.
There is also old (deprecated) syntax that uses / .. / instead of [= .. =]
and ? instead of *.
<tag/clist/
Clist is similar to a set, except that unlike other sets, it can be
......@@ -1200,9 +1202,9 @@ foot).
<tag/eclist/
Eclist is a data type used for BGP extended community lists. Eclists
are very similar to clists, but they are sets of ECs instead of pairs.
The same operations (like <cf/add/, <cf/delete/, or <cf/&tilde;/
membership operator) can be used to modify or test eclists, with ECs
instead of pairs as arguments.
The same operations (like <cf/add/, <cf/delete/ or <cf/&tilde;/ and
<cf/!&tilde;/ membership operators) can be used to modify or test
eclists, with ECs instead of pairs as arguments.
</descrip>
......@@ -1211,19 +1213,19 @@ foot).
<p>The filter language supports common integer operators <cf>(+,-,*,/)</cf>,
parentheses <cf/(a*(b+c))/, comparison <cf/(a=b, a!=b, a&lt;b, a&gt;=b)/.
Logical operations include unary not (<cf/!/), and (<cf/&amp;&amp;/) and or
(<cf/&verbar;&verbar;/). Special operators include <cf/&tilde;/ for "is element
of a set" operation - it can be used on element and set of elements of the same
type (returning true if element is contained in the given set), or on two
strings (returning true if first string matches a shell-like pattern stored in
second string) or on IP and prefix (returning true if IP is within the range
defined by that prefix), or on prefix and prefix (returning true if first prefix
is more specific than second one) or on bgppath and bgpmask (returning true if
the path matches the mask) or on number and bgppath (returning true if the
number is in the path) or on bgppath and int (number) set (returning true if any
ASN from the path is in the set) or on pair/quad and clist (returning true if
the pair/quad is element of the clist) or on clist and pair/quad set (returning
true if there is an element of the clist that is also a member of the pair/quad
set).
(<cf/&verbar;&verbar;/). Special operators include (<cf/&tilde;/,
<cf/!&tilde;/) for "is (not) element of a set" operation - it can be used on
element and set of elements of the same type (returning true if element is
contained in the given set), or on two strings (returning true if first string
matches a shell-like pattern stored in second string) or on IP and prefix
(returning true if IP is within the range defined by that prefix), or on prefix
and prefix (returning true if first prefix is more specific than second one) or
on bgppath and bgpmask (returning true if the path matches the mask) or on
number and bgppath (returning true if the number is in the path) or on bgppath
and int (number) set (returning true if any ASN from the path is in the set) or
on pair/quad and clist (returning true if the pair/quad is element of the
clist) or on clist and pair/quad set (returning true if there is an element of
the clist that is also a member of the pair/quad set).
<p>There is one operator related to ROA infrastructure - <cf/roa_check()/. It
examines a ROA table and does RFC 6483 route origin validation for a given
......@@ -1312,7 +1314,7 @@ clist for most purposes.
<cf/RTS_DUMMY/, <cf/RTS_STATIC/, <cf/RTS_INHERIT/, <cf/RTS_DEVICE/,
<cf/RTS_STATIC_DEVICE/, <cf/RTS_REDIRECT/, <cf/RTS_RIP/, <cf/RTS_OSPF/,
<cf/RTS_OSPF_IA/, <cf/RTS_OSPF_EXT1/, <cf/RTS_OSPF_EXT2/, <cf/RTS_BGP/,
<cf/RTS_PIPE/.
<cf/RTS_PIPE/, <cf/RTS_BABEL/.
<tag><m/enum/ cast</tag>
Route type (Currently <cf/RTC_UNICAST/ for normal routes,
......@@ -1475,8 +1477,37 @@ protocol babel [<name>] {
yes.
</descrip>
<sect1>Attributes
<p>Babel defines just one attribute: the internal babel metric of the route. It
is exposed as the <cf/babel_metric/ attribute and has range from 1 to infinity
(65535).
<sect1>Example
<p><code>
protocol babel {
interface "eth*" {
type wired;
};
interface "wlan0", "wlan1" {
type wireless;
hello interval 1;
rxcost 512;
};
interface "tap0";
# This matches the default of babeld: redistribute all addresses
# configured on local interfaces, plus re-distribute all routes received
# from other babel peers.
export where (source = RTS_DEVICE) || (source = RTS_BABEL);
}
</code>
<sect><label id="sect-bfd">BFD
<sect>BFD
<label id="sect-bfd">
<sect1>Introduction
......@@ -2358,6 +2389,17 @@ limitations can be overcome using another routing table and the pipe protocol.
protocol work with. Available only on systems supporting multiple
routing tables.
<tag>metric <m/number/</tag> (Linux)
Use specified value as a kernel metric (priority) for all routes sent to
the kernel. When multiple routes for the same network are in the kernel
routing table, the Linux kernel chooses one with lower metric. Also,
routes with different metrics do not clash with each other, therefore
using dedicated metric value is a reliable way to avoid overwriting
routes from other sources (e.g. kernel device routes). Metric 0 has a
special meaning of undefined metric, in which either OS default is used,
or per-route metric can be set using <cf/krt_metric/ attribute. Default:
0 (undefined).
<tag>graceful restart <m/switch/</tag>
Participate in graceful restart recovery. If this option is enabled and
a graceful restart recovery is active, the Kernel protocol will defer
......@@ -2390,9 +2432,11 @@ these attributes:
route. See /etc/iproute2/rt_protos for common values. On BSD, it is
based on STATIC and PROTOx flags. The attribute is read-only.
<tag>int <cf/krt_metric/</tag>
<tag>int <cf/krt_metric/</tag> (Linux)
The kernel metric of the route. When multiple same routes are in a
kernel routing table, the Linux kernel chooses one with lower metric.
Note that preferred way to set kernel metric is to use protocol option
<cf/metric/, unless per-route metric values are needed.
<tag>ip <cf/krt_prefsrc/</tag> (Linux)
The preferred source address. Used in source address selection for
......@@ -2400,6 +2444,15 @@ these attributes:
<tag>int <cf/krt_realm/</tag> (Linux)
The realm of the route. Can be used for traffic classification.
<tag>int <cf/krt_scope/</tag> (Linux IPv4)
The scope of the route. Valid values are 0-254, although Linux kernel
may reject some values depending on route type and nexthop. It is
supposed to represent `indirectness' of the route, where nexthops of
routes are resolved through routes with a higher scope, but in current
kernels anything below <it/link/ (253) is treated as <it/global/ (0).
When not present, global scope is implied for all routes except device
routes, where link scope is used by default.
</descrip>
<p>In Linux, there is also a plenty of obscure route attributes mostly focused
......
......@@ -618,16 +618,17 @@ bgp_path:
;
bgp_path_tail1:
NUM bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN; $$->val = $1; }
| '*' bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASTERISK; $$->val = 0; }
| '?' bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_QUESTION; $$->val = 0; }
| bgp_path_expr bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN_EXPR; $$->val = (uintptr_t) $1; }
| { $$ = NULL; }
NUM bgp_path_tail1 { $$ = cfg_allocz(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN; $$->val = $1; }
| NUM DDOT NUM bgp_path_tail1 { $$ = cfg_allocz(sizeof(struct f_path_mask)); $$->next = $4; $$->kind = PM_ASN_RANGE; $$->val = $1; $$->val2 = $3; }
| '*' bgp_path_tail1 { $$ = cfg_allocz(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASTERISK; }
| '?' bgp_path_tail1 { $$ = cfg_allocz(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_QUESTION; }
| bgp_path_expr bgp_path_tail1 { $$ = cfg_allocz(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN_EXPR; $$->val = (uintptr_t) $1; }
| { $$ = NULL; }
;
bgp_path_tail2:
NUM bgp_path_tail2 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN; $$->val = $1; }
| '?' bgp_path_tail2 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASTERISK; $$->val = 0; }
NUM bgp_path_tail2 { $$ = cfg_allocz(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN; $$->val = $1; }
| '?' bgp_path_tail2 { $$ = cfg_allocz(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASTERISK; }
| { $$ = NULL; }
;
......@@ -725,6 +726,7 @@ term:
| term '>' term { $$ = f_new_inst(); $$->code = '<'; $$->a1.p = $3; $$->a2.p = $1; }
| term GEQ term { $$ = f_new_inst(); $$->code = P('<','='); $$->a1.p = $3; $$->a2.p = $1; }
| term '~' term { $$ = f_new_inst(); $$->code = '~'; $$->a1.p = $1; $$->a2.p = $3; }
| term NMA term { $$ = f_new_inst(); $$->code = P('!','~'); $$->a1.p = $1; $$->a2.p = $3; }
| '!' term { $$ = f_new_inst(); $$->code = '!'; $$->a1.p = $2; }
| DEFINED '(' term ')' { $$ = f_new_inst(); $$->code = P('d','e'); $$->a1.p = $3; }
......
......@@ -81,6 +81,10 @@ pm_format(struct f_path_mask *p, buffer *buf)
buffer_puts(buf, "* ");
break;
case PM_ASN_RANGE:
buffer_print(buf, "%u..%u ", p->val, p->val2);
break;
case PM_ASN_EXPR:
buffer_print(buf, "%u ", f_eval_asn((struct f_inst *) p->val));
break;
......@@ -146,18 +150,29 @@ val_compare(struct f_val v1, struct f_val v2)
}
static int
pm_path_same(struct f_path_mask *m1, struct f_path_mask *m2)
pm_same(struct f_path_mask *m1, struct f_path_mask *m2)
{
while (m1 && m2)
{
if ((m1->kind != m2->kind) || (m1->val != m2->val))
if (m1->kind != m2->kind)
return 0;
if (m1->kind == PM_ASN_EXPR)
{
if (!i_same((struct f_inst *) m1->val, (struct f_inst *) m2->val))
return 0;
}
else
{
if ((m1->val != m2->val) || (m1->val2 != m2->val2))
return 0;
}
m1 = m1->next;
m2 = m2->next;
}
return !m1 && !m2;
return !m1 && !m2;
}
/**
......@@ -182,7 +197,7 @@ val_same(struct f_val v1, struct f_val v2)
switch (v1.type) {
case T_PATH_MASK:
return pm_path_same(v1.val.path_mask, v2.val.path_mask);
return pm_same(v1.val.path_mask, v2.val.path_mask);
case T_PATH:
case T_CLIST:
case T_ECLIST:
......@@ -673,6 +688,16 @@ interpret(struct f_inst *what)
runtime( "~ applied on unknown type pair" );
res.val.i = !!res.val.i;
break;
case P('!','~'):
TWOARGS;
res.type = T_BOOL;
res.val.i = val_in_range(v1, v2);
if (res.val.i == CMP_ERROR)
runtime( "!~ applied on unknown type pair" );
res.val.i = !res.val.i;
break;
case P('d','e'):
ONEARG;
res.type = T_BOOL;
......@@ -1415,7 +1440,8 @@ i_same(struct f_inst *f1, struct f_inst *f2)
case P('A','p'): TWOARGS; break;
case P('C','a'): TWOARGS; break;
case P('a','f'):
case P('a','l'): ONEARG; break;
case P('a','l'):
case P('a','L'): ONEARG; break;
#if 0
case P('R','C'):
TWOARGS;
......
......@@ -96,22 +96,28 @@ clist l2;
eclist el;
eclist el2;
{
print "Entering path test...";
pm1 = / 4 3 2 1 /;
pm2 = [= 4 3 2 1 =];
pm2 = [= 3..6 3 2 1..2 =];
print "Testing path masks: ", pm1, " ", pm2;
p2 = prepend( + empty +, 1 );
p2 = prepend( p2, 2 );
p2 = prepend( p2, 3 );
p2 = prepend( p2, 4 );
print "Testing paths: ", p2;
print "Testing path: (4 3 2 1) = ", p2;
print "Should be true: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 3 ~ p2, " ", p2 ~ [2, 10..20], " ", p2 ~ [4, 10..20];
print "4 = ", p2.len;
p2 = prepend( p2, 5 );
print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2, " ", p2 ~ [8, ten..(2*ten)];
print "Testing path: (5 4 3 2 1) = ", p2;
print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2, " ", p2 ~ [8, ten..(2*ten)], " ", p2 ~ [= 1..4 4 3 2 1 =], " ", p2 ~ [= 5 4 4..100 2 1 =];
print "Should be true: ", p2 ~ / ? 4 3 2 1 /, " ", p2, " ", / ? 4 3 2 1 /;
print "Should be true: ", p2 ~ [= * 4 3 * 1 =], " ", p2, " ", [= * 4 3 * 1 =];
print "Should be true: ", p2 ~ [= 5..6 4..10 1..3 1..3 1..65536 =];
print "Should be true: ", p2 ~ [= (3+2) (2*2) 3 2 1 =], " ", p2 ~ mkpath(5, 4);
print "Should be true: ", p2.len = 5, " ", p2.first = 5, " ", p2.last = 1;
print "Should be true: ", pm1 = [= 4 3 2 1 =], " ", pm1 != [= 4 3 1 2 =], " ",
pm2 = [= 3..6 3 2 1..2 =], " ", pm2 != [= 3..6 3 2 1..3 =], " ",
[= 1 2 (1+2) =] = [= 1 2 (1+2) =], " ", [= 1 2 (1+2) =] != [= 1 2 (2+1) =];
print "5 = ", p2.len;
print "Delete 3: ", delete(p2, 3);
print "Filter 1-3: ", filter(p2, [1..3]);
......
......@@ -82,7 +82,7 @@ build_tree(struct f_tree *from)
if (len <= 1024)
buf = alloca(len * sizeof(struct f_tree *));
else
buf = malloc(len * sizeof(struct f_tree *));
buf = xmalloc(len * sizeof(struct f_tree *));
/* Convert a degenerated tree into an sorted array */
i = 0;
......@@ -94,7 +94,7 @@ build_tree(struct f_tree *from)
root = build_tree_rec(buf, 0, len);
if (len > 1024)
free(buf);
xfree(buf);
return root;
}
......@@ -163,9 +163,9 @@ tree_format(struct f_tree *t, buffer *buf)
{
buffer_puts(buf, "[");
tree_node_format(t, buf);
tree_node_format(t, buf);
/* Undo last separator */
/* Undo last separator */
if (buf->pos[-1] != '[')
buf->pos -= 2;
......
......@@ -169,7 +169,7 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
case ' ': flags |= SPACE; goto repeat;
case '#': flags |= SPECIAL; goto repeat;
case '0': flags |= ZEROPAD; goto repeat;
}
}
/* get field width */
field_width = -1;
......
Summary: BIRD Internet Routing Daemon
Name: bird
Version: 1.6.0
Version: 1.6.2
Release: 1
Copyright: GPL
Group: Networking/Daemons
......
......@@ -435,18 +435,23 @@ parse_path(struct adata *path, struct pm_pos *pos)
static int
pm_match(struct pm_pos *pos, u32 asn)
pm_match(struct pm_pos *pos, u32 asn, u32 asn2)
{
u32 gas;
if (! pos->set)
return pos->val.asn == asn;
return ((pos->val.asn >= asn) && (pos->val.asn <= asn2));
u8 *p = pos->val.sp;
int len = *p++;
int i;
for (i = 0; i < len; i++)
if (get_as(p + i * BS) == asn)
{
gas = get_as(p + i * BS);
if ((gas >= asn) && (gas <= asn2))
return 1;
}
return 0;
}
......@@ -490,7 +495,7 @@ pm_mark(struct pm_pos *pos, int i, int plen, int *nl, int *nh)
* next part of mask, we advance each marked state.
* We start with marked first position, when we
* run out of marked positions, we reject. When
* we process the whole mask, we accept iff final position
* we process the whole mask, we accept if final position
* (auxiliary position after last real position in AS path)
* is marked.
*/
......@@ -502,6 +507,7 @@ as_path_match(struct adata *path, struct f_path_mask *mask)
int plen = parse_path(path, pos);
int l, h, i, nh, nl;
u32 val = 0;
u32 val2 = 0;
/* l and h are bound of interval of positions where
are marked states */
......@@ -525,12 +531,16 @@ as_path_match(struct adata *path, struct f_path_mask *mask)
h = plen;
break;
case PM_ASN:
val = mask->val;
case PM_ASN: /* Define single ASN as ASN..ASN - very narrow interval */
val2 = val = mask->val;
goto step;
case PM_ASN_EXPR:
val = f_eval_asn((struct f_inst *) mask->val);
val2 = val = f_eval_asn((struct f_inst *) mask->val);
goto step;
case PM_ASN_RANGE:
val = mask->val;
val2 = mask->val2;
goto step;
case PM_QUESTION:
step:
nh = nl = -1;
......@@ -538,7 +548,7 @@ as_path_match(struct adata *path, struct f_path_mask *mask)
if (pos[i].mark)
{
pos[i].mark = 0;
if ((mask->kind == PM_QUESTION) || pm_match(pos + i, val))
if ((mask->kind == PM_QUESTION) || pm_match(pos + i, val, val2))
pm_mark(pos, i, plen, &nl, &nh);
}
......
......@@ -45,11 +45,13 @@ struct adata *as_path_filter(struct linpool *pool, struct adata *path, struct f_
#define PM_QUESTION 1
#define PM_ASTERISK 2
#define PM_ASN_EXPR 3
#define PM_ASN_RANGE 4
struct f_path_mask {
struct f_path_mask *next;
int kind;
uintptr_t val;
uintptr_t val2;
};
int as_path_match(struct adata *path, struct f_path_mask *mask);
......
......@@ -74,7 +74,7 @@ CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CL
CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS)
CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE)
RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE, BABEL)
CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE, UNDEFINED)
CF_ENUM(T_ENUM_RTC, RTC_, UNICAST, BROADCAST, MULTICAST, ANYCAST)
CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT, MULTIPATH)
......
......@@ -287,7 +287,7 @@ void rte_update2(struct channel *c, net_addr *n, rte *new, struct rte_src *src);
/* rte_update() moved to protocol.h to avoid dependency conflicts */
void rte_discard(rtable *tab, rte *old);
int rt_examine(rtable *t, net_addr *a, struct proto *p, struct filter *filter);
rte *rt_export_merged(struct channel *c, net *net, rte **rt_free, struct ea_list **tmpa, int silent);
rte *rt_export_merged(struct channel *c, net *net, rte **rt_free, struct ea_list **tmpa, linpool *pool, int silent);
void rt_refresh_begin(rtable *t, struct channel *c);
void rt_refresh_end(rtable *t, struct channel *c);
void rt_schedule_prune(rtable *t);
......@@ -509,6 +509,8 @@ int mpnh__same(struct mpnh *x, struct mpnh *y); /* Compare multipath nexthops */
static inline int mpnh_same(struct mpnh *x, struct mpnh *y)
{ return (x == y) || mpnh__same(x, y); }
struct mpnh *mpnh_merge(struct mpnh *x, struct mpnh *y, int rx, int ry, int max, linpool *lp);
void mpnh_insert(struct mpnh **n, struct mpnh *y);
int mpnh_is_sorted(struct mpnh *x);
void rta_init(void);
rta *rta_lookup(rta *); /* Get rta equivalent to this one, uc++ */
......