summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2009-11-09 22:54:39 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2009-11-09 22:54:39 +0100
commit3f22fa9e74c8643d3e4f7e3a7b4f2aa992ad09f5 (patch)
tree703e2606e1f01118098ad662f0ecc54c0c48fcd6
parenta6bc04d59130c49a1dbfadffa4285b11e2ff4939 (diff)
parentb7c0e93ebd40cdc4f6e89067a3e5f7293263c7f9 (diff)
Merge branch 'dev' into ospf3
-rw-r--r--NEWS25
-rw-r--r--aclocal.m41
-rw-r--r--client/client.c20
-rw-r--r--conf/Makefile4
-rw-r--r--configure.in8
-rw-r--r--doc/bird.sgml41
-rw-r--r--doc/prog-head.sgml3
-rw-r--r--filter/config.Y4
-rw-r--r--filter/filter.c35
-rw-r--r--filter/filter.h3
-rw-r--r--filter/test.conf1
-rw-r--r--filter/trie.c2
-rw-r--r--lib/birdlib.h2
-rw-r--r--lib/event.c4
-rw-r--r--lib/mempool.c5
-rw-r--r--lib/resource.c6
-rw-r--r--lib/slab.c1
-rw-r--r--lib/socket.h2
-rw-r--r--misc/bird.spec2
-rw-r--r--nest/a-path.c17
-rw-r--r--nest/attrs.h3
-rw-r--r--nest/config.Y6
-rw-r--r--nest/proto.c5
-rw-r--r--nest/protocol.h8
-rw-r--r--nest/rt-attr.c2
-rw-r--r--nest/rt-table.c104
-rw-r--r--proto/bgp/attrs.c7
-rw-r--r--proto/bgp/bgp.c20
-rw-r--r--proto/bgp/bgp.h2
-rw-r--r--proto/bgp/config.Y4
-rw-r--r--proto/bgp/packets.c29
-rw-r--r--proto/ospf/config.Y5
-rw-r--r--proto/ospf/ospf.h2
-rw-r--r--proto/pipe/pipe.c3
-rw-r--r--proto/rip/config.Y2
-rw-r--r--sysdep/bsd/krt-sock.c5
-rw-r--r--sysdep/config.h2
-rw-r--r--sysdep/linux/krt-scan.c6
-rw-r--r--sysdep/linux/netlink/netlink.Y5
-rw-r--r--sysdep/linux/netlink/netlink.c38
-rw-r--r--sysdep/unix/io.c96
-rw-r--r--tools/Makefile.in21
-rwxr-xr-xtools/config.guess147
-rwxr-xr-xtools/config.sub199
44 files changed, 688 insertions, 219 deletions
diff --git a/NEWS b/NEWS
index 391d4f70..0b2e4ee9 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,28 @@
+Version 1.1.5 (2009-10-29)
+ o Better scalability of BGP.
+ o New accessors for AS path - first and last.
+ o Allows to set protocol-specific router ID.
+ o Allows import kernel 'onlink' routes.
+ o Endianity check in buildsystem changed.
+
+Version 1.1.4 (2009-10-02)
+ o BGP passive option.
+ o Several minor bugfixes.
+
+Version 1.1.3 (2009-09-11)
+ o Bugfix in core
+ o Bugfix in BGP related to AS2->AS4 conversion.
+
+Version 1.1.2 (2009-08-23)
+ o Allow more kernel routing tables in IPv6.
+ o Bugfix in core
+
+Version 1.1.1 (2009-08-14)
+ o 'more' style paging in BIRD client.
+ o Important core bug fixed.
+ o Portability to non-x86 related bugfixes.
+ o As usual, miscellaneous bugfixes.
+
Version 1.1.0 (2009-06-28)
o Parametrized pair and path mask expressions in the filter language.
o Transparent pipe mode allows to implement BGP route server with
diff --git a/aclocal.m4 b/aclocal.m4
index f3b89530..c5af7895 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -26,6 +26,7 @@ for size in 1 2 4 ; do
done
])
+dnl BIRD_CHECK_ENDIAN is unused and obsolete
AC_DEFUN(BIRD_CHECK_ENDIAN,
[AC_CACHE_CHECK([CPU endianity], bird_cv_c_endian,[
AC_TRY_RUN([
diff --git a/client/client.c b/client/client.c
index ea8f8d31..88a6095f 100644
--- a/client/client.c
+++ b/client/client.c
@@ -333,17 +333,18 @@ static void
server_got_reply(char *x)
{
int code;
+ int len = 0;
if (*x == '+') /* Async reply */
- skip_input || printf(">>> %s\n", x+1);
+ skip_input || (len = printf(">>> %s\n", x+1));
else if (x[0] == ' ') /* Continuation */
- skip_input || printf("%s%s\n", verbose ? " " : "", x+1);
+ skip_input || (len = printf("%s%s\n", verbose ? " " : "", x+1));
else if (strlen(x) > 4 &&
sscanf(x, "%d", &code) == 1 && code >= 0 && code < 10000 &&
(x[4] == ' ' || x[4] == '-'))
{
if (code)
- skip_input || printf("%s\n", verbose ? x : x+5);
+ skip_input || (len = printf("%s\n", verbose ? x : x+5));
if (x[4] == ' ')
{
nstate = STATE_PROMPT;
@@ -352,14 +353,19 @@ server_got_reply(char *x)
}
}
else
- skip_input || printf("??? <%s>\n", x);
+ skip_input || (len = printf("??? <%s>\n", x));
if (skip_input)
return;
- num_lines++;
- if (interactive && input_initialized && (num_lines >= LINES) && (cstate == STATE_CMD_SERVER))
- more();
+ if (interactive && input_initialized && (len > 0))
+ {
+ int lns = LINES ? LINES : 25;
+ int cls = COLS ? COLS : 80;
+ num_lines += (len + cls - 1) / cls; /* Divide and round up */
+ if ((num_lines >= lns) && (cstate == STATE_CMD_SERVER))
+ more();
+ }
}
static void
diff --git a/conf/Makefile b/conf/Makefile
index dae3dd18..5d729a42 100644
--- a/conf/Makefile
+++ b/conf/Makefile
@@ -11,7 +11,9 @@ BISON_DEBUG=-t
#FLEX_DEBUG=-d
endif
-cf-parse.tab.c cf-parse-tab.h: cf-parse.y
+cf-parse.tab.h: cf-parse.tab.c
+
+cf-parse.tab.c: cf-parse.y
$(BISON) -bcf-parse -dv -pcf_ $(BISON_DEBUG) cf-parse.y
cf-parse.y: $(conf-fragments) $(conf-src)/gen_parser.m4
diff --git a/configure.in b/configure.in
index 89cf9701..ec2417b2 100644
--- a/configure.in
+++ b/configure.in
@@ -123,6 +123,10 @@ else
;;
ipv4:freebsd*) sysdesc=bsd
;;
+ ipv6:kfreebsd*) sysdesc=bsd-v6
+ ;;
+ ipv4:kfreebsd*) sysdesc=bsd
+ ;;
ipv6:openbsd*) sysdesc=bsd-v6
;;
ipv4:openbsd*) sysdesc=bsd
@@ -177,8 +181,10 @@ AC_TRY_COMPILE([#include <sys/types.h>
AC_DEFINE(HAVE_SIN_LEN,,sin_len)],
AC_MSG_RESULT(no))
+AC_C_BIGENDIAN([AC_DEFINE(CPU_BIG_ENDIAN)], [AC_DEFINE(CPU_LITTLE_ENDIAN)],
+ [AC_MSG_ERROR([Cannot determine CPU endianity.])])
+
BIRD_CHECK_INTEGERS
-BIRD_CHECK_ENDIAN
BIRD_CHECK_STRUCT_ALIGN
BIRD_CHECK_TIME_T
BIRD_CHECK_STRUCT_IP_MREQN
diff --git a/doc/bird.sgml b/doc/bird.sgml
index 267c768a..0c2b8fbe 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -23,7 +23,8 @@ configuration primitives, <cf> is fragment of configuration within normal text,
<author>
Ondrej Filip <it/&lt;feela@network.cz&gt;/,
Pavel Machek <it/&lt;pavel@ucw.cz&gt;/,
-Martin Mares <it/&lt;mj@ucw.cz&gt;/
+Martin Mares <it/&lt;mj@ucw.cz&gt;/,
+Ondrej Zajicek <it/&lt;santiago@crfreenet.org&gt;/
</author>
<abstract>
@@ -296,6 +297,10 @@ to zero to disable it. An empty <cf><m/switch/</cf> is equivalent to <cf/on/
<cf/events/ for events internal to the protocol and
<cf/packets/ for packets sent and received by the protocol. Default: off.
+ <tag>router id <m/IPv4 address/</tag> This option can be used to override global
+ router id for a given protocol. This option is not yet implemented for OSPF
+ protocol. Default: uses global router id.
+
<tag>import all | none | filter <m/name/ | filter { <m/filter commands/ } | where <m/filter expression/</tag>
Specify a filter to be used for filtering routes coming from the protocol to the routing table. <cf/all/ is shorthand for <cf/where true/ and <cf/none/ is shorthand for <cf/where false/. Default: <cf/all/.
@@ -478,7 +483,7 @@ This argument can be omitted if there exists only a single instance.
switch itself to the new configuration, protocols are
reconfigured if possible, restarted otherwise. Changes in
filters usualy lead to restart of affected protocols. If
- <cf/soft> option is used, changes in filters does not cause
+ <cf/soft/ option is used, changes in filters does not cause
BIRD to restart affected protocols, therefore already accepted
routes (according to old filters) would be still propagated,
but new routes would be processed according to the new
@@ -648,6 +653,21 @@ incompatible with each other (that is to prevent you from shooting in the foot).
<tag/bgppath/
BGP path is a list of autonomous system numbers. You can't write literals of this type.
+ There are several special operators on bgppaths:
+
+ <cf><m/P/.first</cf> returns the first ASN (the neighbor ASN) in path <m/P/.
+
+ <cf><m/P/.last</cf> returns the last ASN (the source ASN) in path <m/P/.
+
+ Both <cf/first/ and <cf/last/ return zero if there is no appropriate ASN,
+ for example if the path contains an AS set element as the first (or the last) part.
+
+ <cf><m/P/.len</cf> returns the length of path <m/P/.
+
+ <cf>prepend(<m/P/,<m/A/)</cf> prepends ASN <m/A/ to path <m/P/ and returns the result.
+ Statement <cf><m/P/ = prepend(<m/P/, <m/A/);</cf> can be shortened to
+ <cf><m/P/.prepend(<m/A/);</cf> if <m/P/ is appropriate route attribute
+ (for example <cf/bgp_path/).
<tag/bgpmask/
BGP masks are patterns used for BGP path matching
@@ -661,10 +681,20 @@ incompatible with each other (that is to prevent you from shooting in the foot).
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 *.
+
<tag/clist/
Community list is similar to set of pairs,
except that unlike other sets, it can be modified.
There exist no literals of this type.
+ There are two special operators on clists:
+
+ <cf>add(<m/C/,<m/P/)</cf> adds pair <m/P/ to clist <m/C/ and returns the result.
+
+ <cf>delete(<m/C/,<m/P/)</cf> deletes pair <m/P/ from clist <m/C/ and returns the result.
+
+ Statement <cf><m/C/ = add(<m/C/, <m/P/);</cf> can be shortened to
+ <cf><m/C/.add(<m/P/);</cf> if <m/C/ is appropriate route attribute
+ (for example <cf/bgp_community/). Similarly for <cf/delete/.
</descrip>
@@ -723,7 +753,7 @@ defined by using the <cf>defined( <m>attribute</m> )</cf> operator.
Address scope of the network (<cf/SCOPE_HOST/ for addresses local to this host, <cf/SCOPE_LINK/ for those specific for a physical link, <cf/SCOPE_SITE/ and <cf/SCOPE_ORGANIZATION/ for private addresses, <cf/SCOPE_UNIVERSE/ for globally visible addresses).
<tag><m/int/ preference</tag>
- Preference of the route. (See the chapter about routing tables.)
+ Preference of the route. Valid values are 0-65535. (See the chapter about routing tables.)
<tag><m/ip/ from</tag>
The router which the route has originated from. Read-only.
@@ -867,6 +897,11 @@ for each neighbor using the following configuration parameters:
of BGP sessions. Default: no authentication. Password has to be set by
external utility (e.g. setkey(8)) on BSD systems.
+ <tag>passive <m/switch/</tag> Standard BGP behavior is both
+ initiating outgoing connections and accepting incoming
+ connections. In passive mode, outgoing connections are not
+ initiated. Default: off.
+
<tag>rr client</tag> Be a route reflector and treat the neighbor as
a route reflection client. Default: disabled.
diff --git a/doc/prog-head.sgml b/doc/prog-head.sgml
index 5e527e5f..0eec367e 100644
--- a/doc/prog-head.sgml
+++ b/doc/prog-head.sgml
@@ -13,7 +13,8 @@
<author>
Ondrej Filip <it/&lt;feela@network.cz&gt;/,
Pavel Machek <it/&lt;pavel@ucw.cz&gt;/,
-Martin Mares <it/&lt;mj@ucw.cz&gt;/
+Martin Mares <it/&lt;mj@ucw.cz&gt;/,
+Ondrej Zajicek <it/&lt;santiago@crfreenet.org&gt;/
</author>
<abstract>
diff --git a/filter/config.Y b/filter/config.Y
index ee4e638d..22206d09 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -36,7 +36,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
LEN,
DEFINED,
ADD, DELETE, CONTAINS, RESET,
- PREPEND, MATCH,
+ PREPEND, FIRST, LAST, MATCH,
EMPTY,
FILTER, WHERE, EVAL)
@@ -448,6 +448,8 @@ term:
| term '.' IP { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_IP; }
| term '.' LEN { $$ = f_new_inst(); $$->code = 'L'; $$->a1.p = $1; }
| term '.' MASK '(' term ')' { $$ = f_new_inst(); $$->code = P('i','M'); $$->a1.p = $1; $$->a2.p = $5; }
+ | term '.' FIRST { $$ = f_new_inst(); $$->code = P('a','f'); $$->a1.p = $1; }
+ | term '.' LAST { $$ = f_new_inst(); $$->code = P('a','l'); $$->a1.p = $1; }
/* Communities */
/* This causes one shift/reduce conflict
diff --git a/filter/filter.c b/filter/filter.c
index 3df0f0c6..07a25f4a 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -291,7 +291,6 @@ static struct rte **f_rte, *f_rte_old;
static struct linpool *f_pool;
static struct ea_list **f_tmp_attrs;
static int f_flags;
-static rta *f_rta_copy;
/*
* rta_cow - prepare rta for modification by filter
@@ -299,8 +298,8 @@ static rta *f_rta_copy;
static void
rta_cow(void)
{
- if (!f_rta_copy) {
- f_rta_copy = lp_alloc(f_pool, sizeof(rta));
+ if ((*f_rte)->attrs->aflags & RTAF_CACHED) {
+ rta *f_rta_copy = lp_alloc(f_pool, sizeof(rta));
memcpy(f_rta_copy, (*f_rte)->attrs, sizeof(rta));
f_rta_copy->aflags = 0;
*f_rte = rte_cow(*f_rte);
@@ -354,6 +353,7 @@ interpret(struct f_inst *what)
struct f_val v1, v2, res;
unsigned u1, u2;
int i;
+ u32 as;
res.type = T_VOID;
if (!what)
@@ -665,6 +665,7 @@ interpret(struct f_inst *what)
struct adata *ad = lp_alloc(f_pool, sizeof(struct adata) + len);
ad->length = len;
(* (ip_addr *) ad->data) = v1.val.px.ip;
+ l->attrs[0].u.ptr = ad;
break;
case EAF_TYPE_AS_PATH:
if (v1.type != T_PATH)
@@ -686,8 +687,8 @@ interpret(struct f_inst *what)
if (!(what->aux & EAF_TEMP) && (!(f_flags & FF_FORCE_TMPATTR))) {
rta_cow();
- l->next = f_rta_copy->eattrs;
- f_rta_copy->eattrs = l;
+ l->next = (*f_rte)->attrs->eattrs;
+ (*f_rte)->attrs->eattrs = l;
} else {
l->next = (*f_tmp_attrs);
(*f_tmp_attrs) = l;
@@ -702,6 +703,8 @@ interpret(struct f_inst *what)
ONEARG;
if (v1.type != T_INT)
runtime( "Can't set preference to non-integer" );
+ if ((v1.val.i < 0) || (v1.val.i > 0xFFFF))
+ runtime( "Setting preference value out of bounds" );
*f_rte = rte_cow(*f_rte);
(*f_rte)->pref = v1.val.i;
break;
@@ -725,6 +728,26 @@ interpret(struct f_inst *what)
default: bug( "Unknown prefix to conversion" );
}
break;
+ case P('a','f'): /* Get first ASN from AS PATH */
+ ONEARG;
+ if (v1.type != T_PATH)
+ runtime( "AS Path expected" );
+
+ as = 0;
+ as_path_get_first(v1.val.ad, &as);
+ res.type = T_INT;
+ res.val.i = as;
+ break;
+ case P('a','l'): /* Get last ASN from AS PATH */
+ ONEARG;
+ if (v1.type != T_PATH)
+ runtime( "AS path expected" );
+
+ as = 0;
+ as_path_get_last(v1.val.ad, &as);
+ res.type = T_INT;
+ res.val.i = as;
+ break;
case 'r':
ONEARG;
res = v1;
@@ -944,7 +967,6 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc
f_tmp_attrs = tmp_attrs;
f_rte = rte;
f_rte_old = *rte;
- f_rta_copy = NULL;
f_pool = tmp_pool;
inst = filter->root;
res = interpret(inst);
@@ -965,7 +987,6 @@ f_eval_int(struct f_inst *expr)
f_tmp_attrs = NULL;
f_rte = NULL;
f_rte_old = NULL;
- f_rta_copy = NULL;
f_pool = cfg_mem;
res = interpret(expr);
if (res.type != T_INT)
diff --git a/filter/filter.h b/filter/filter.h
index 8e0d1793..e526a79b 100644
--- a/filter/filter.h
+++ b/filter/filter.h
@@ -81,10 +81,13 @@ struct rte;
int f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags);
int f_eval_int(struct f_inst *expr);
+u32 f_eval_asn(struct f_inst *expr);
+
char *filter_name(struct filter *filter);
int filter_same(struct filter *new, struct filter *old);
int i_same(struct f_inst *f1, struct f_inst *f2);
+void f_prefix_get_bounds(struct f_prefix *px, int *l, int *h);
void f_prefix_get_bounds(struct f_prefix *px, int *l, int *h);
int val_compare(struct f_val v1, struct f_val v2);
diff --git a/filter/test.conf b/filter/test.conf
index f3b79619..7114fd28 100644
--- a/filter/test.conf
+++ b/filter/test.conf
@@ -62,6 +62,7 @@ clist l;
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 ~ [= (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 "5 = ", p2.len;
pm1 = [= 1 2 * 3 4 5 =];
diff --git a/filter/trie.c b/filter/trie.c
index 2257c8b6..fb405ded 100644
--- a/filter/trie.c
+++ b/filter/trie.c
@@ -70,6 +70,7 @@
*/
#include "nest/bird.h"
+#include "lib/string.h"
#include "conf/conf.h"
#include "filter/filter.h"
@@ -177,7 +178,6 @@ trie_add_prefix(struct f_trie *t, struct f_prefix *px)
{
int l, h;
int plen = px->len & LEN_MASK;
- ip_addr pmask = ipa_mkmask(plen);
/* 'l' and 'h' are lower and upper bounds on accepted
prefix lengths, both inclusive. 0 <= l, h <= 32 */
diff --git a/lib/birdlib.h b/lib/birdlib.h
index b7cd6b43..12a581b7 100644
--- a/lib/birdlib.h
+++ b/lib/birdlib.h
@@ -13,7 +13,7 @@
/* Ugly structure offset handling macros */
-#define OFFSETOF(s, i) ((unsigned int)&((s *)0)->i)
+#define OFFSETOF(s, i) ((size_t) &((s *)0)->i)
#define SKIP_BACK(s, i, p) ((s *)((char *)p - OFFSETOF(s, i)))
#define BIRD_ALIGN(s, a) (((s)+a-1)&~(a-1))
diff --git a/lib/event.c b/lib/event.c
index 55a9c487..d556cd05 100644
--- a/lib/event.c
+++ b/lib/event.c
@@ -63,10 +63,6 @@ event *
ev_new(pool *p)
{
event *e = ralloc(p, &ev_class);
-
- e->hook = NULL;
- e->data = NULL;
- e->n.next = NULL;
return e;
}
diff --git a/lib/mempool.c b/lib/mempool.c
index e6f277b9..0cb06b58 100644
--- a/lib/mempool.c
+++ b/lib/mempool.c
@@ -19,6 +19,7 @@
*/
#include <stdlib.h>
+#include <stdint.h>
#include "nest/bird.h"
#include "lib/resource.h"
@@ -64,13 +65,9 @@ linpool
*lp_new(pool *p, unsigned blk)
{
linpool *m = ralloc(p, &lp_class);
- m->ptr = m->end = NULL;
- m->first = m->current = NULL;
m->plast = &m->first;
- m->first_large = NULL;
m->chunk_size = blk;
m->threshold = 3*blk/4;
- m->total = m->total_large = 0;
return m;
}
diff --git a/lib/resource.c b/lib/resource.c
index 8f91450c..5ba23f18 100644
--- a/lib/resource.c
+++ b/lib/resource.c
@@ -8,6 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include "nest/bird.h"
#include "lib/resource.h"
@@ -183,13 +184,14 @@ rdump(void *res)
*
* This function is called by the resource classes to create a new
* resource of the specified class and link it to the given pool.
- * Size of the resource structure is taken from the @size field
- * of the &resclass.
+ * Allocated memory is zeroed. Size of the resource structure is taken
+ * from the @size field of the &resclass.
*/
void *
ralloc(pool *p, struct resclass *c)
{
resource *r = xmalloc(c->size);
+ bzero(r, c->size);
r->class = c;
add_tail(&p->inside, &r->n);
diff --git a/lib/slab.c b/lib/slab.c
index 17511d21..8cce52fe 100644
--- a/lib/slab.c
+++ b/lib/slab.c
@@ -26,6 +26,7 @@
*/
#include <stdlib.h>
+#include <stdint.h>
#include "nest/bird.h"
#include "lib/resource.h"
diff --git a/lib/socket.h b/lib/socket.h
index 0ab7d951..f44e8e88 100644
--- a/lib/socket.h
+++ b/lib/socket.h
@@ -53,13 +53,13 @@ int sk_set_ttl(sock *s, int ttl); /* Set TTL for given socket */
/* Add or remove security associations for given passive socket */
int sk_set_md5_auth(sock *s, ip_addr a, char *passwd);
+int sk_rx_ready(sock *s);
/* Prepare UDP or IP socket to multicasting. s->iface and s->ttl must be set */
int sk_setup_multicast(sock *s);
int sk_join_group(sock *s, ip_addr maddr);
int sk_leave_group(sock *s, ip_addr maddr);
-
static inline int
sk_send_buffer_empty(sock *sk)
{
diff --git a/misc/bird.spec b/misc/bird.spec
index 56aed5b9..021fba2f 100644
--- a/misc/bird.spec
+++ b/misc/bird.spec
@@ -1,6 +1,6 @@
Summary: BIRD Internet Routing Daemon
Name: bird
-Version: 1.0.16
+Version: 1.1.5
Release: 1
Copyright: GPL
Group: Networking/Daemons
diff --git a/nest/a-path.c b/nest/a-path.c
index 5aacf8f2..c804619b 100644
--- a/nest/a-path.c
+++ b/nest/a-path.c
@@ -13,6 +13,7 @@
#include "lib/resource.h"
#include "lib/unaligned.h"
#include "lib/string.h"
+#include "filter/filter.h"
/* Global AS4 support, shared by all BGP instances.
@@ -188,6 +189,12 @@ int
as_path_getlen(struct adata *path)
{
int bs = bgp_as4_support ? 4 : 2;
+ return as_path_getlen_int(path, bs);
+}
+
+int
+as_path_getlen_int(struct adata *path, int bs)
+{
int res = 0;
u8 *p = path->data;
u8 *q = p+path->length;
@@ -206,7 +213,7 @@ as_path_getlen(struct adata *path)
}
int
-as_path_get_first(struct adata *path, u32 *orig_as)
+as_path_get_last(struct adata *path, u32 *orig_as)
{
int bs = bgp_as4_support ? 4 : 2;
int found = 0;
@@ -222,8 +229,7 @@ as_path_get_first(struct adata *path, u32 *orig_as)
case AS_PATH_SET:
if (len = *p++)
{
- found = 1;
- res = get_as(p);
+ found = 0;
p += bs * len;
}
break;
@@ -239,12 +245,13 @@ as_path_get_first(struct adata *path, u32 *orig_as)
}
}
- *orig_as = res;
+ if (found)
+ *orig_as = res;
return found;
}
int
-as_path_get_last(struct adata *path, u32 *last_as)
+as_path_get_first(struct adata *path, u32 *last_as)
{
u8 *p = path->data;
diff --git a/nest/attrs.h b/nest/attrs.h
index b838ce96..16fb35af 100644
--- a/nest/attrs.h
+++ b/nest/attrs.h
@@ -9,6 +9,8 @@
#ifndef _BIRD_ATTRS_H_
#define _BIRD_ATTRS_H_
+#include <stdint.h>
+
/* a-path.c */
#define AS_PATH_SET 1 /* Types of path segments */
@@ -28,6 +30,7 @@ int as_path_convert_to_old(struct adata *path, byte *dst, int *new_used);
int as_path_convert_to_new(struct adata *path, byte *dst, int req_as);
void as_path_format(struct adata *path, byte *buf, unsigned int size);
int as_path_getlen(struct adata *path);
+int as_path_getlen_int(struct adata *path, int bs);
int as_path_get_first(struct adata *path, u32 *orig_as);
int as_path_get_last(struct adata *path, u32 *last_as);
int as_path_is_member(struct adata *path, u32 as);
diff --git a/nest/config.Y b/nest/config.Y
index dc31224a..4721112a 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -44,7 +44,7 @@ CF_KEYWORDS(ROUTER, ID, PROTOCOL, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE)
-CF_KEYWORDS(LISTEN, BGP, V6ONLY, ADDRESS, PORT)
+CF_KEYWORDS(LISTEN, BGP, V6ONLY, ADDRESS, PORT, PASSWORDS)
CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE)
@@ -132,7 +132,7 @@ proto_name:
proto_item:
/* EMPTY */
| PREFERENCE expr {
- if ($2 < 0 || $2 > 255) cf_error("Invalid preference");
+ if ($2 < 0 || $2 > 0xFFFF) cf_error("Invalid preference");
this_proto->preference = $2;
}
| DISABLED bool { this_proto->disabled = $2; }
@@ -140,6 +140,7 @@ proto_item:
| IMPORT imexport { this_proto->in_filter = $2; }
| EXPORT imexport { this_proto->out_filter = $2; }
| TABLE rtable { this_proto->table = $2; }
+ | ROUTER ID idval { this_proto->router_id = $3; }
;
imexport:
@@ -293,6 +294,7 @@ password_item_params:
;
+
/* Core commands */
CF_CLI_HELP(SHOW, ..., [[Show status information]])
diff --git a/nest/proto.c b/nest/proto.c
index 2af077b8..7bb1286d 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -313,6 +313,7 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
&& nc->preference == oc->preference
&& nc->disabled == oc->disabled
&& nc->table->table == oc->table->table
+ && proto_get_router_id(nc) == proto_get_router_id(oc)
&& ((type == RECONFIG_SOFT) || filter_same(nc->in_filter, oc->in_filter))
&& ((type == RECONFIG_SOFT) || filter_same(nc->out_filter, oc->out_filter))
&& p->proto_state != PS_DOWN)
@@ -515,7 +516,9 @@ static void
proto_fell_down(struct proto *p)
{
DBG("Protocol %s down\n", p->name);
- ASSERT(p->stats.imp_routes == 0);
+
+ if (p->stats.imp_routes != 0)
+ log(L_ERR "Protocol %s is down but still has %d routes", p->name, p->stats.imp_routes);
bzero(&p->stats, sizeof(struct proto_stats));
rt_unlock_table(p->table);
diff --git a/nest/protocol.h b/nest/protocol.h
index 0f9d59d8..484df846 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -12,6 +12,7 @@
#include "lib/lists.h"
#include "lib/resource.h"
#include "lib/timer.h"
+#include "conf/conf.h"
struct iface;
struct ifa;
@@ -81,6 +82,7 @@ struct proto_config {
struct proto *proto; /* Instance we've created */
char *name;
unsigned debug, preference, disabled; /* Generic parameters */
+ u32 router_id; /* Protocol specific router ID */
struct rtable_config *table; /* Table we're attached to */
struct filter *in_filter, *out_filter; /* Attached filters */
@@ -192,6 +194,12 @@ struct proto *proto_get_named(struct symbol *, struct protocol *);
void proto_xxable(char *, int);
void proto_debug(char *, unsigned int);
+static inline u32
+proto_get_router_id(struct proto_config *pc)
+{
+ return pc->router_id ? pc->router_id : pc->global->router_id;
+}
+
extern list active_proto_list;
/*
diff --git a/nest/rt-attr.c b/nest/rt-attr.c
index de63198e..9d78ce07 100644
--- a/nest/rt-attr.c
+++ b/nest/rt-attr.c
@@ -74,7 +74,7 @@ ea__find(ea_list *e, unsigned id)
if (e->flags & EALF_BISECT)
{
l = 0;
- r = e->count + 1;
+ r = e->count - 1;
while (l <= r)
{
m = (l+r) / 2;
diff --git a/nest/rt-table.c b/nest/rt-table.c
index fb2feaca..87bf0dc7 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -427,57 +427,87 @@ rte_recalculate(rtable *table, net *net, struct proto *p, struct proto *src, rte
rte_announce(table, RA_ANY, net, new, old, tmpa);
- if (new && rte_better(new, old_best)) /* It's a new optimal route => announce and relink it */
+
+ if (new && rte_better(new, old_best))
{
+ /* The first case - the new route is cleary optimal, we link it
+ at the first position and announce it */
+
rte_trace_in(D_ROUTES, p, new, "added [best]");
rte_announce(table, RA_OPTIMAL, net, new, old_best, tmpa);
new->next = net->routes;
net->routes = new;
}
- else
+ else if (old == old_best)
{
- if (old == old_best) /* It has _replaced_ the old optimal route */
+ /* The second case - the old best route disappeared, we add the
+ new route (if we have any) to the list (we don't care about
+ position) and then we elect the new optimal route and relink
+ that route at the first position and announce it. New optimal
+ route might be NULL if there is no more routes */
+
+ /* Add the new route to the list */
+ if (new)
{
- r = new; /* Find new optimal route and announce it */
- for(s=net->routes; s; s=s->next)
- if (rte_better(s, r))
- r = s;
- rte_announce(table, RA_OPTIMAL, net, r, old_best, tmpa);
- if (r) /* Re-link the new optimal route */
+ rte_trace_in(D_ROUTES, p, new, "added");
+ new->next = net->routes;
+ net->routes = new;
+ }
+
+ /* Find new optimal route */
+ r = NULL;
+ for (s=net->routes; s; s=s->next)
+ if (rte_better(s, r))
+ r = s;
+
+ /* Announce optimal route */
+ rte_announce(table, RA_OPTIMAL, net, r, old_best, tmpa);
+
+ /* And relink it (if there is any) */
+ if (r)
+ {
+ k = &net->routes;
+ while (s = *k)
{
- k = &net->routes;
- while (s = *k)
+ if (s == r)
{
- if (s == r)
- {
- *k = r->next;
- break;
- }
- k = &s->next;
+ *k = r->next;
+ break;
}
- r->next = net->routes;
- net->routes = r;
+ k = &s->next;
}
- else if (table->gc_counter++ >= table->config->gc_max_ops &&
- table->gc_time + table->config->gc_min_time <= now)
- ev_schedule(table->gc_event);
- }
- if (new) /* Link in the new non-optimal route */
- {
- new->next = old_best->next;
- old_best->next = new;
- rte_trace_in(D_ROUTES, p, new, "added");
- }
- else if (old && (p->debug & D_ROUTES))
- {
- if (old != old_best)
- rte_trace_in(D_ROUTES, p, old, "removed");
- else if (net->routes)
- rte_trace_in(D_ROUTES, p, old, "removed [replaced]");
- else
- rte_trace_in(D_ROUTES, p, old, "removed [sole]");
+ r->next = net->routes;
+ net->routes = r;
}
+ else if (table->gc_counter++ >= table->config->gc_max_ops &&
+ table->gc_time + table->config->gc_min_time <= now)
+ ev_schedule(table->gc_event);
+ }
+ else if (new)
+ {
+ /* The third case - the new route is not better than the old
+ best route (therefore old_best != NULL) and the old best
+ route was not removed (therefore old_best == net->routes).
+ We just link the new route after the old best route. */
+
+ ASSERT(net->routes != NULL);
+ new->next = net->routes->next;
+ net->routes->next = new;
+ rte_trace_in(D_ROUTES, p, new, "added");
}
+ else if (old && (p->debug & D_ROUTES))
+ {
+ /* Not really a case - the list of routes is correct, we just
+ log the route removal */
+
+ if (old != old_best)
+ rte_trace_in(D_ROUTES, p, old, "removed");
+ else if (net->routes)
+ rte_trace_in(D_ROUTES, p, old, "removed [replaced]");
+ else
+ rte_trace_in(D_ROUTES, p, old, "removed [sole]");
+ }
+
if (old)
{
if (p->rte_remove)
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index d0ec41f9..d839ed09 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -996,7 +996,7 @@ bgp_get_neighbor(rte *r)
eattr *e = ea_find(r->attrs->eattrs, EA_CODE(EAP_BGP, BA_AS_PATH));
u32 as;
- if (e && as_path_get_last(e->u.ptr, &as))
+ if (e && as_path_get_first(e->u.ptr, &as))
return as;
else
return ((struct bgp_proto *) r->attrs->proto)->remote_as;
@@ -1191,7 +1191,7 @@ bgp_reconstruct_4b_atts(struct bgp_proto *p, rta *a, struct linpool *pool)
if (a4)
log(L_WARN "%s: AS4_AGGREGATOR attribute received, but AGGREGATOR attribute is missing", p->p.name);
- int p2_len = as_path_getlen(p2->u.ptr);
+ int p2_len = as_path_getlen_int(p2->u.ptr, 2);
int p4_len = p4 ? validate_as4_path(p, p4->u.ptr) : -1;
if (p4 && (p4_len < 0))
@@ -1247,7 +1247,6 @@ bgp_decode_attrs(struct bgp_conn *conn, byte *attr, unsigned int len, struct lin
int errcode;
byte *z, *attr_start;
byte seen[256/8];
- eattr *e;
ea_list *ea;
struct adata *ad;
@@ -1471,7 +1470,7 @@ bgp_get_route_info(rte *e, byte *buf, ea_list *attrs)
u32 origas;
buf += bsprintf(buf, " (%d) [", e->pref);
- if (p && as_path_get_first(p->u.ptr, &origas))
+ if (p && as_path_get_last(p->u.ptr, &origas))
buf += bsprintf(buf, "AS%u", origas);
if (o)
buf += bsprintf(buf, "%c", "ie?"[o->u.data]);
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index 0c8ee6da..b38c6b13 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -120,7 +120,9 @@ bgp_startup(struct bgp_proto *p)
{
BGP_TRACE(D_EVENTS, "Started");
p->start_state = p->cf->capabilities ? BSS_CONNECT : BSS_CONNECT_NOCAP;
- bgp_active(p);
+
+ if (!p->cf->passive)
+ bgp_active(p);
}
static void
@@ -292,7 +294,8 @@ bgp_decision(void *vp)
DBG("BGP: Decision start\n");
if ((p->p.proto_state == PS_START)
- && (p->outgoing_conn.state == BS_IDLE))
+ && (p->outgoing_conn.state == BS_IDLE)
+ && (!p->cf->passive))
bgp_active(p);
if ((p->p.proto_state == PS_STOP)
@@ -428,8 +431,15 @@ bgp_hold_timeout(timer *t)
{
struct bgp_conn *conn = t->data;
- DBG("BGP: Hold timeout, closing connection\n");
- bgp_error(conn, 4, 0, NULL, 0);
+ DBG("BGP: Hold timeout\n");
+
+ /* If there is something in input queue, we are probably congested
+ and perhaps just not processed BGP packets in time. */
+
+ if (sk_rx_ready(conn->sk) > 0)
+ bgp_start_timer(conn->hold_timer, 10);
+ else
+ bgp_error(conn, 4, 0, NULL, 0);
}
static void
@@ -679,7 +689,7 @@ bgp_start_locked(struct object_lock *lock)
}
DBG("BGP: Got lock\n");
- p->local_id = cf->c.global->router_id;
+ p->local_id = proto_get_router_id(&cf->c);
p->next_hop = cf->multihop ? cf->multihop_via : cf->remote_ip;
p->neigh = neigh_find(&p->p, &p->next_hop, NEF_STICKY);
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index 9bbdab8e..0a82be2b 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -9,6 +9,7 @@
#ifndef _BIRD_BGP_H_
#define _BIRD_BGP_H_
+#include <stdint.h>
#include "nest/route.h"
struct linpool;
@@ -32,6 +33,7 @@ struct bgp_config {
int rs_client; /* Whether neighbor is RS client of me */
int advertise_ipv4; /* Whether we should add IPv4 capability advertisement to OPEN message */
u32 route_limit; /* Number of routes that may be imported, 0 means disable limit */
+ int passive; /* Do not initiate outgoing connection */
unsigned connect_retry_time;
unsigned hold_time, initial_hold_time;
unsigned keepalive_time;
diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y
index 872fb271..7360820f 100644
--- a/proto/bgp/config.Y
+++ b/proto/bgp/config.Y
@@ -22,7 +22,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN, BGP_NEXT_HOP,
BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS,
PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4, ADVERTISE, IPV4,
- CAPABILITIES, LIMIT)
+ CAPABILITIES, LIMIT, PASSIVE)
CF_GRAMMAR
@@ -34,7 +34,6 @@ bgp_proto_start: proto_start BGP {
BGP_CFG->hold_time = 240;
BGP_CFG->connect_retry_time = 120;
BGP_CFG->initial_hold_time = 240;
- BGP_CFG->default_med = 0;
BGP_CFG->compare_path_lengths = 1;
BGP_CFG->start_delay_time = 5;
BGP_CFG->error_amnesia_time = 300;
@@ -78,6 +77,7 @@ bgp_proto:
| bgp_proto ADVERTISE IPV4 bool ';' { BGP_CFG->advertise_ipv4 = $4; }
| bgp_proto PASSWORD TEXT ';' { BGP_CFG->password = $3; }
| bgp_proto ROUTE LIMIT expr ';' { BGP_CFG->route_limit = $4; }
+ | bgp_proto PASSIVE bool ';' { BGP_CFG->passive = $3; }
;
CF_ADDTO(dynamic_attr, BGP_PATH
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index ac697be1..d126fe5f 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -234,7 +234,7 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
{
struct bgp_proto *p = conn->bgp;
struct bgp_bucket *buck;
- int size;
+ int size, second;
int remains = BGP_MAX_PACKET_LENGTH - BGP_HEADER_LENGTH - 4;
byte *w, *tmp, *tstart;
ip_addr *ipp, ip, ip_ll;
@@ -292,7 +292,9 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
nh = ea_find(buck->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
ASSERT(nh);
- /* We have two addresses here in 'nh'. Really. */
+ /* We have two addresses here in 'nh'. Really.
+ Unless NEXT_HOP was modified by filter */
+ second = (nh->u.ptr->length == NEXT_HOP_LENGTH);
ipp = (ip_addr *) nh->u.ptr->data;
ip = ipp[0];
ip_ll = IPA_NONE;
@@ -316,7 +318,7 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
n = neigh_find(&p->p, &ip, 0);
if (n && n->iface == p->neigh->iface)
{
- if (ipa_nonzero(ipp[1]))
+ if (second && ipa_nonzero(ipp[1]))
ip_ll = ipp[1];
else
{
@@ -569,7 +571,6 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, int len)
{
struct bgp_conn *other;
struct bgp_proto *p = conn->bgp;
- struct bgp_config *cf = p->cf;
unsigned hold;
u16 base_as;
u32 id;
@@ -601,7 +602,17 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, int len)
log(L_WARN "%s: Peer advertised inconsistent AS numbers", p->p.name);
if (conn->advertised_as != p->remote_as)
- { bgp_error(conn, 2, 2, (byte *) &(conn->advertised_as), -4); return; }
+ {
+ if (conn->peer_as4_support)
+ {
+ u32 val = htonl(conn->advertised_as);
+ bgp_error(conn, 2, 2, (byte *) &val, 4);
+ }
+ else
+ bgp_error(conn, 2, 2, pkt+20, 2);
+
+ return;
+ }
/* Check the other connection */
other = (conn == &p->outgoing_conn) ? &p->incoming_conn : &p->outgoing_conn;
@@ -973,11 +984,19 @@ bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned
{
*t++ = ':';
*t++ = ' ';
+
+ if ((code == 2) && (subcode == 2) && ((len == 2) || (len == 4)))
+ {
+ /* Bad peer AS - we would like to print the AS */
+ t += bsprintf(t, "%d", (len == 2) ? get_u16(data) : get_u32(data));
+ goto done;
+ }
if (len > 16)
len = 16;
for (i=0; i<len; i++)
t += bsprintf(t, "%02x", data[i]);
}
+ done:
*t = 0;
log(L_REMOTE "%s: %s: %s%s", p->p.name, msg, name, argbuf);
}
diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y
index 7b2641b2..f75e8eb5 100644
--- a/proto/ospf/config.Y
+++ b/proto/ospf/config.Y
@@ -45,12 +45,13 @@ finish_iface_config(struct ospf_iface_patt *ip)
CF_DECLS
-CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG)
+CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG, BROADCAST)
CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE)
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, LINK)
-CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY, LSADB)
+CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY)
+CF_KEYWORDS(WAIT, DELAY, LSADB)
%type <t> opttext
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h
index 3e33e453..5a11418f 100644
--- a/proto/ospf/ospf.h
+++ b/proto/ospf/ospf.h
@@ -786,6 +786,8 @@ static inline void schedule_link_lsa(struct ospf_iface *ifa) {}
void ospf_sh_neigh(struct proto *p, char *iff);
void ospf_sh(struct proto *p);
void ospf_sh_iface(struct proto *p, char *iff);
+void ospf_sh_state(struct proto *p, int verbose);
+
#define EA_OSPF_METRIC1 EA_CODE(EAP_OSPF, 0)
#define EA_OSPF_METRIC2 EA_CODE(EAP_OSPF, 1)
diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c
index 8ff430a9..e57c9efd 100644
--- a/proto/pipe/pipe.c
+++ b/proto/pipe/pipe.c
@@ -62,11 +62,14 @@ pipe_send(struct pipe_proto *p, rtable *dest, net *n, rte *new, rte *old, ea_lis
a.eattrs = attrs;
e = rte_get_temp(&a);
e->net = nn;
+ e->pflags = 0;
if (p->mode == PIPE_TRANSPARENT)
{
/* Copy protocol specific embedded attributes. */
memcpy(&(e->u), &(new->u), sizeof(e->u));
+ e->pref = new->pref;
+ e->pflags = new->pflags;
}
src = new->attrs->proto;
diff --git a/proto/rip/config.Y b/proto/rip/config.Y
index 9a11069e..2df0c5c8 100644
--- a/proto/rip/config.Y
+++ b/proto/rip/config.Y
@@ -24,7 +24,7 @@ CF_DEFINES
CF_DECLS
-CF_KEYWORDS(RIP, INFINITY, METRIC, PORT, PERIOD, GARBAGE, TIMEOUT, PASSWORDS,
+CF_KEYWORDS(RIP, INFINITY, METRIC, PORT, PERIOD, GARBAGE, TIMEOUT,
MODE, BROADCAST, MULTICAST, QUIET, NOLISTEN, VERSION1,
AUTHENTICATION, NONE, PLAINTEXT, MD5,
HONOR, NEVER, NEIGHBOR, ALWAYS,
diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c
index 2e8f1b83..4842a6b8 100644
--- a/sysdep/bsd/krt-sock.c
+++ b/sysdep/bsd/krt-sock.c
@@ -339,7 +339,10 @@ krt_read_rt(struct ks_msg *msg, struct krt_proto *p, int scan)
if (ng && ng->scope)
a.iface = ng->iface;
else
- log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d", igate, net->n.prefix, net->n.pxlen);
+ {
+ log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d", igate, net->n.prefix, net->n.pxlen);
+ return;
+ }
a.dest = RTD_ROUTER;
a.gw = igate;
diff --git a/sysdep/config.h b/sysdep/config.h
index 54f36745..03399bd0 100644
--- a/sysdep/config.h
+++ b/sysdep/config.h
@@ -7,7 +7,7 @@
#define _BIRD_CONFIG_H_
/* BIRD version */
-#define BIRD_VERSION "1.1.0"
+#define BIRD_VERSION "1.1.5"
/* Include parameters determined by configure script */
#include "sysdep/autoconf.h"
diff --git a/sysdep/linux/krt-scan.c b/sysdep/linux/krt-scan.c
index b7fc1295..feb128ef 100644
--- a/sysdep/linux/krt-scan.c
+++ b/sysdep/linux/krt-scan.c
@@ -103,8 +103,10 @@ krt_parse_entry(byte *ent, struct krt_proto *p)
if (ng && ng->scope)
a.iface = ng->iface;
else
- /* FIXME: Remove this warning? Handle it somehow... */
- log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d", gw, net->n.prefix, net->n.pxlen);
+ {
+ log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d", gw, net->n.prefix, net->n.pxlen);
+ return;
+ }
a.dest = RTD_ROUTER;
a.gw = gw;
}
diff --git a/sysdep/linux/netlink/netlink.Y b/sysdep/linux/netlink/netlink.Y
index c448d895..c5dcf620 100644
--- a/sysdep/linux/netlink/netlink.Y
+++ b/sysdep/linux/netlink/netlink.Y
@@ -18,13 +18,8 @@ CF_ADDTO(kern_proto, kern_proto nl_item ';')
nl_item:
KERNEL TABLE expr {
-#ifndef IPV6
if ($3 <= 0 || $3 >= NL_NUM_TABLES)
cf_error("Kernel routing table number out of range");
-#else
- if ($3 != 254)
- cf_error("Linux implementation of IPv6 doesn't support multiple routing tables");
-#endif
THIS_KRT->scan.table_id = $3;
}
;
diff --git a/sysdep/linux/netlink/netlink.c b/sysdep/linux/netlink/netlink.c
index 6cfb0ba6..f45fe159 100644
--- a/sysdep/linux/netlink/netlink.c
+++ b/sysdep/linux/netlink/netlink.c
@@ -691,18 +691,34 @@ nl_parse_route(struct nlmsghdr *h, int scan)
ra.dest = RTD_ROUTER;
memcpy(&ra.gw, RTA_DATA(a[RTA_GATEWAY]), sizeof(ra.gw));
ipa_ntoh(ra.gw);
- ng = neigh_find2(&p->p, &ra.gw, ifa, 0);
- if (ng && ng->scope)
- {
- if (ng->iface != ifa)
- log(L_WARN "KRT: Route with unexpected iface for %I/%d", net->n.prefix, net->n.pxlen);
- ra.iface = ng->iface;
- }
+
+ if (i->rtm_flags & RTNH_F_ONLINK)
+ {
+ /* route with 'onlink' attribute */
+ ra.iface = if_find_by_index(oif);
+ if (ra.iface == NULL)
+ {
+ log(L_WARN "Kernel told us to use unknown interface %u for %I/%d",
+ oif, net->n.prefix, net->n.pxlen);
+ return;
+ }
+ }
else
- {
- log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d", ra.gw, net->n.prefix, net->n.pxlen);
- return;
- }
+ {
+ ng = neigh_find2(&p->p, &ra.gw, ifa, 0);
+ if (ng && ng->scope)
+ {
+ if (ng->iface != ifa)
+ log(L_WARN "KRT: Route with unexpected iface for %I/%d", net->n.prefix, net->n.pxlen);
+ ra.iface = ng->iface;
+ }
+ else
+ {
+ log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d", ra.gw, net->n.prefix, net->n.pxlen);
+ return;
+ }
+
+ }
}
else
{
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index 5cc80dcd..3eb2e03c 100644
--- a/sysdep/unix/io.c
+++ b/sysdep/unix/io.c
@@ -30,12 +30,17 @@
#include "lib/unix.h"
#include "lib/sysio.h"
-/* Maximum number of calls of rx/tx handler for one socket in one
+/* Maximum number of calls of tx handler for one socket in one
* select iteration. Should be small enough to not monopolize CPU by
* one protocol instance.
*/
#define MAX_STEPS 4
+/* Maximum number of calls of rx handler for all sockets in one select
+ iteration. RX callbacks are often much more costly so we limit
+ this to gen small latencies */
+#define MAX_RX_STEPS 4
+
/*
* Tracked Files
*/
@@ -205,10 +210,6 @@ timer *
tm_new(pool *p)
{
timer *t = ralloc(p, &tm_class);
- t->hook = NULL;
- t->data = NULL;
- t->randomize = 0;
- t->expires = 0;
return t;
}
@@ -497,6 +498,7 @@ tm_format_reltime(char *x, bird_clock_t t)
static list sock_list;
static struct birdsock *current_sock;
+static struct birdsock *stored_sock;
static int sock_recalc_fdsets_p;
static inline sock *
@@ -545,6 +547,8 @@ sk_free(resource *r)
close(s->fd);
if (s == current_sock)
current_sock = sk_next(s);
+ if (s == stored_sock)
+ stored_sock = sk_next(s);
rem_node(&s->n);
sock_recalc_fdsets_p = 1;
}
@@ -595,22 +599,9 @@ sk_new(pool *p)
{
sock *s = ralloc(p, &sk_class);
s->pool = p;
- s->data = NULL;
- s->saddr = s->daddr = IPA_NONE;
- s->sport = s->dport = 0;
+ // s->saddr = s->daddr = IPA_NONE;
s->tos = s->ttl = -1;
- s->flags = 0;
- s->iface = NULL;
- s->rbuf = NULL;
- s->rx_hook = NULL;
- s->rbsize = 0;
- s->tbuf = NULL;
- s->tx_hook = NULL;
- s->tbsize = 0;
- s->err_hook = NULL;
s->fd = -1;
- s->rbuf_alloc = s->tbuf_alloc = NULL;
- s->password = NULL;
return s;
}
@@ -1169,6 +1160,29 @@ sk_maybe_write(sock *s)
}
}
+int
+sk_rx_ready(sock *s)
+{
+ fd_set rd, wr;
+ struct timeval timo;
+ int rv;
+
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ FD_SET(s->fd, &rd);
+
+ timo.tv_sec = 0;
+ timo.tv_usec = 0;
+
+ redo:
+ rv = select(s->fd+1, &rd, &wr, NULL, &timo);
+
+ if ((rv < 0) && (errno == EINTR || errno == EAGAIN))
+ goto redo;
+
+ return rv;
+}
+
/**
* sk_send - send data to a socket
* @s: socket
@@ -1337,6 +1351,9 @@ io_init(void)
srandom((int) now_real);
}
+static int short_loops = 0;
+#define SHORT_LOOP_MAX 10
+
void
io_loop(void)
{
@@ -1415,8 +1432,8 @@ io_loop(void)
}
/* And finally enter select() to find active sockets */
-
hi = select(hi+1, &rd, &wr, NULL, &timo);
+
if (hi < 0)
{
if (errno == EINTR || errno == EAGAIN)
@@ -1425,13 +1442,17 @@ io_loop(void)
}
if (hi)
{
- current_sock = SKIP_BACK(sock, n, HEAD(sock_list)); /* guaranteed to be non-empty */
+ /* guaranteed to be non-empty */
+ current_sock = SKIP_BACK(sock, n, HEAD(sock_list));
+
while (current_sock)
{
sock *s = current_sock;
int e;
- int steps = MAX_STEPS;
- if (FD_ISSET(s->fd, &rd) && s->rx_hook)
+ int steps;
+
+ steps = MAX_STEPS;
+ if ((s->type >= SK_MAGIC) && FD_ISSET(s->fd, &rd) && s->rx_hook)
do
{
steps--;
@@ -1454,6 +1475,35 @@ io_loop(void)
current_sock = sk_next(s);
next: ;
}
+
+ short_loops++;
+ if (events && (short_loops < SHORT_LOOP_MAX))
+ continue;
+ short_loops = 0;
+
+ int count = 0;
+ current_sock = stored_sock;
+ if (current_sock == NULL)
+ current_sock = SKIP_BACK(sock, n, HEAD(sock_list));
+
+ while (current_sock && count < MAX_RX_STEPS)
+ {
+ sock *s = current_sock;
+ int e;
+ int steps;
+
+ if ((s->type < SK_MAGIC) && FD_ISSET(s->fd, &rd) && s->rx_hook)
+ {
+ count++;
+ e = sk_read(s);
+ if (s != current_sock)
+ goto next2;
+ }
+ current_sock = sk_next(s);
+ next2: ;
+ }
+
+ stored_sock = current_sock;
}
}
}
diff --git a/tools/Makefile.in b/tools/Makefile.in
index 6307cf07..daa753c3 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -11,17 +11,29 @@ daemon: $(exedir)/bird
client: $(exedir)/birdc
-subdir depend: .dir-stamp
+bird-dep := $(addsuffix /all.o, $(static-dirs)) conf/all.o lib/birdlib.a
+
+$(bird-dep): sysdep/paths.h .dep-stamp subdir
+
+birdc-dep := client/all.o lib/birdlib.a
+
+$(birdc-dep): sysdep/paths.h .dep-stamp subdir
+
+depend: sysdep/paths.h .dir-stamp
+ set -e ; for a in $(dynamic-dirs) ; do $(MAKE) -C $$a $@ ; done
+ set -e ; for a in $(static-dirs) $(client-dirs) ; do $(MAKE) -C $$a -f $(srcdir_abs)/$$a/Makefile $@ ; done
+
+subdir: sysdep/paths.h .dir-stamp .dep-stamp
set -e ; for a in $(dynamic-dirs) ; do $(MAKE) -C $$a $@ ; done
set -e ; for a in $(static-dirs) $(client-dirs) ; do $(MAKE) -C $$a -f $(srcdir_abs)/$$a/Makefile $@ ; done
-$(exedir)/bird: $(addsuffix /all.o, $(static-dirs)) conf/all.o lib/birdlib.a
+$(exedir)/bird: $(bird-dep)
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
-$(exedir)/birdc: client/all.o lib/birdlib.a
+$(exedir)/birdc: $(birdc-dep)
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(CLIENT_LIBS)
-.dir-stamp:
+.dir-stamp: sysdep/paths.h
mkdir -p $(static-dirs) $(client-dirs) $(doc-dirs)
touch .dir-stamp
@@ -60,6 +72,7 @@ install-docs:
clean:
find . -name "*.[oa]" -o -name core -o -name depend -o -name "*.html" | xargs rm -f
+ rm -f conf/cf-lex.c conf/cf-parse.* conf/commands.h conf/keywords.h
rm -f $(exedir)/bird $(exedir)/birdc $(exedir)/bird.ctl $(exedir)/bird6.ctl .dep-stamp
distclean: clean
diff --git a/tools/config.guess b/tools/config.guess
index ad5281e6..da833146 100755
--- a/tools/config.guess
+++ b/tools/config.guess
@@ -1,9 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
-timestamp='2005-08-03'
+timestamp='2009-04-27'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -55,8 +56,8 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -106,7 +107,7 @@ set_cc_for_build='
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
@@ -160,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
@@ -206,8 +208,11 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:ekkoBSD:*:*)
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
macppc:MirBSD:*:*)
- echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
exit ;;
*:MirBSD:*:*)
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
@@ -319,14 +324,30 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
- i86pc:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@@ -527,7 +548,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
- *:AIX:*:[45])
+ *:AIX:*:[456])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@@ -764,12 +785,19 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ case ${UNAME_MACHINE} in
+ pc98)
+ echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
- i*:MINGW*:*)
+ *:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:windows32*:*)
@@ -779,9 +807,18 @@ EOF
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
- x86:Interix*:[34]*)
- echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
- exit ;;
+ *:Interix*:[3456]*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ EM64T | authenticamd | genuineintel)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
@@ -815,6 +852,16 @@ EOF
echo ${UNAME_MACHINE}-pc-minix
exit ;;
arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
cris:Linux:*:*)
@@ -851,7 +898,11 @@ EOF
#endif
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^CPU/{
+ s: ::g
+ p
+ }'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
mips64:Linux:*:*)
@@ -870,7 +921,11 @@ EOF
#endif
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^CPU/{
+ s: ::g
+ p
+ }'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
or32:Linux:*:*)
@@ -896,6 +951,9 @@ EOF
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-gnu
+ exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
@@ -919,9 +977,15 @@ EOF
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
@@ -940,9 +1004,6 @@ EOF
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit ;;
- coff-i386)
- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit ;;
"")
# Either a pre-BFD a.out linker (linux-gnuoldld) or
# one that does not give us useful --help.
@@ -964,7 +1025,7 @@ EOF
LIBC=gnulibc1
# endif
#else
- #ifdef __INTEL_COMPILER
+ #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
LIBC=gnu
#else
LIBC=gnuaout
@@ -974,7 +1035,11 @@ EOF
LIBC=dietlibc
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^LIBC/{
+ s: ::g
+ p
+ }'`"
test x"${LIBC}" != x && {
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
exit
@@ -1053,8 +1118,11 @@ EOF
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
@@ -1092,6 +1160,16 @@ EOF
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
@@ -1167,6 +1245,9 @@ EOF
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@@ -1176,6 +1257,15 @@ EOF
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
@@ -1185,7 +1275,6 @@ EOF
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
case $UNAME_PROCESSOR in
- *86) UNAME_PROCESSOR=i686 ;;
unknown) UNAME_PROCESSOR=powerpc ;;
esac
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
@@ -1264,6 +1353,12 @@ EOF
i*86:skyos:*:*)
echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
@@ -1424,9 +1519,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
diff --git a/tools/config.sub b/tools/config.sub
index 1c366dfd..a39437d0 100755
--- a/tools/config.sub
+++ b/tools/config.sub
@@ -1,9 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
-timestamp='2005-07-08'
+timestamp='2009-04-17'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -71,8 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -119,8 +120,10 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
- nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
- kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+ nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -171,6 +174,10 @@ case $os in
-hiux*)
os=-hiuxwe2
;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -187,6 +194,10 @@ case $os in
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -231,20 +242,24 @@ case $basic_machine in
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
- | fr30 | frv \
+ | fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
- | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
- | mips64vr | mips64vrel \
+ | mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
@@ -257,26 +272,26 @@ case $basic_machine in
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
- | ms1 \
+ | moxie \
+ | mt \
| msp430 \
+ | nios | nios2 \
| ns16k | ns32k \
| or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
- | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b \
- | strongarm \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
- | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
- | z8k)
- basic_machine=$basic_machine-unknown
- ;;
- m32c)
+ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+ | z8k | z80)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
@@ -286,6 +301,9 @@ case $basic_machine in
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
@@ -305,25 +323,28 @@ case $basic_machine in
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* \
+ | avr-* | avr32-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
- | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
- | m32r-* | m32rle-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
- | mips64vr-* | mips64vrel-* \
+ | mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
@@ -336,30 +357,33 @@ case $basic_machine in
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
- | ms1-* \
+ | mt-* \
| msp430-* \
+ | nios-* | nios2-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
- | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | xstormy16-* | xtensa*-* \
| ymp-* \
- | z8k-*)
+ | z8k-* | z80-*)
;;
- m32c-*)
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -423,6 +447,10 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-bsd
;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -431,10 +459,22 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
c90)
basic_machine=c90-cray
os=-unicos
;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -463,8 +503,8 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
- cr16c)
- basic_machine=cr16c-unknown
+ cr16)
+ basic_machine=cr16-unknown
os=-elf
;;
crds | unos)
@@ -502,6 +542,10 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
@@ -656,6 +700,14 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -671,6 +723,10 @@ case $basic_machine in
basic_machine=i386-pc
os=-mingw32
;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
miniframe)
basic_machine=m68000-convergent
;;
@@ -696,6 +752,9 @@ case $basic_machine in
basic_machine=i386-pc
os=-msdos
;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
mvs)
basic_machine=i370-ibm
os=-mvs
@@ -794,6 +853,14 @@ case $basic_machine in
basic_machine=i860-intel
os=-osf
;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
pbd)
basic_machine=sparc-tti
;;
@@ -803,6 +870,12 @@ case $basic_machine in
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
@@ -859,6 +932,10 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
+ rdos)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
@@ -885,6 +962,10 @@ case $basic_machine in
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
sei)
basic_machine=mips-sei
os=-seiux
@@ -896,6 +977,9 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
sh64)
basic_machine=sh64-unknown
;;
@@ -985,6 +1069,10 @@ case $basic_machine in
basic_machine=tic6x-unknown
os=-coff
;;
+ tile*)
+ basic_machine=tile-unknown
+ os=-linux-gnu
+ ;;
tx39)
basic_machine=mipstx39-unknown
;;
@@ -1060,6 +1148,10 @@ case $basic_machine in
basic_machine=z8k-unknown
os=-sim
;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
none)
basic_machine=none-none
os=-none
@@ -1098,10 +1190,10 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
- sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
- sparc | sparcv8 | sparcv9 | sparcv9b)
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
basic_machine=sparc-sun
;;
cydra)
@@ -1170,25 +1262,28 @@ case $os in
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -kopensolaris* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
+ | -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku*)
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1318,6 +1413,9 @@ case $os in
-zvmoe)
os=-zvmoe
;;
+ -dicos*)
+ os=-dicos
+ ;;
-none)
;;
*)
@@ -1340,6 +1438,12 @@ else
# system, and we'll never get to this point.
case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
*-acorn)
os=-riscix1.2
;;
@@ -1349,9 +1453,9 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
- c4x-* | tic4x-*)
- os=-coff
- ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
@@ -1377,6 +1481,9 @@ case $basic_machine in
m68*-cisco)
os=-aout
;;
+ mep-*)
+ os=-elf
+ ;;
mips*-cisco)
os=-elf
;;