diff options
-rw-r--r-- | aclocal.m4 | 13 | ||||
-rw-r--r-- | conf/conf.c | 2 | ||||
-rw-r--r-- | configure.in | 17 | ||||
-rw-r--r-- | doc/bird.sgml | 2 | ||||
-rw-r--r-- | filter/config.Y | 9 | ||||
-rw-r--r-- | filter/filter.c | 73 | ||||
-rw-r--r-- | filter/test.conf | 14 | ||||
-rw-r--r-- | nest/rt-attr.c | 1 | ||||
-rw-r--r-- | nest/rt-table.c | 7 | ||||
-rw-r--r-- | sysdep/unix/io.c | 19 | ||||
-rw-r--r-- | sysdep/unix/main.c | 8 | ||||
-rw-r--r-- | sysdep/unix/unix.h | 2 |
12 files changed, 104 insertions, 63 deletions
@@ -147,6 +147,19 @@ if test -z "$bird_cv_sys_linux_version" ; then fi ])]) +AC_DEFUN(BIRD_CHECK_GCC_OPTIONS, +[AC_CACHE_VAL(bird_cv_c_option_no_pointer_sign, [ +cat >conftest.c <<EOF +int main(void) +{ return 0; } +EOF +if $CC -Wall -Wno-pointer-sign conftest.c >&AS_MESSAGE_LOG_FD 2>&1 ; then + bird_cv_c_option_no_pointer_sign=yes +else + bird_cv_c_option_no_pointer_sign=no +fi +])]) + # BIRD_CHECK_PROG_FLAVOR_GNU(PROGRAM-PATH, IF-SUCCESS, [IF-FAILURE]) # copied autoconf internal _AC_PATH_PROG_FLAVOR_GNU m4_define([BIRD_CHECK_PROG_FLAVOR_GNU], diff --git a/conf/conf.c b/conf/conf.c index 58eb10a6..604a412c 100644 --- a/conf/conf.c +++ b/conf/conf.c @@ -114,6 +114,8 @@ config_parse(struct config *c) rt_preconfig(c); cf_parse(); protos_postconfig(c); + if (EMPTY_LIST(c->protos)) + cf_error("No protocol is specified in the config file"); #ifdef IPV6 if (!c->router_id) cf_error("Router ID must be configured manually on IPv6 routers"); diff --git a/configure.in b/configure.in index c931c183..3c988b16 100644 --- a/configure.in +++ b/configure.in @@ -55,17 +55,28 @@ AC_SEARCH_LIBS(clock_gettime,[c rt posix4]) AC_CANONICAL_HOST -AC_MSG_CHECKING([what CFLAGS should we use]) +# Store this value because ac_test_CFLAGS is overwritten by AC_PROG_CC if test "$ac_test_CFLAGS" != set ; then - CFLAGS="$CFLAGS -Wall -Wstrict-prototypes -Wno-pointer-sign -Wno-parentheses" + bird_cflags_default=yes fi -AC_MSG_RESULT($CFLAGS) AC_PROG_CC if test -z "$GCC" ; then AC_MSG_ERROR([This program requires the GNU C Compiler.]) fi +AC_MSG_CHECKING([what CFLAGS should we use]) +if test "$bird_cflags_default" == yes ; then + BIRD_CHECK_GCC_OPTIONS + + CFLAGS="$CFLAGS -Wall -Wstrict-prototypes -Wno-parentheses" + if test "$bird_cv_c_option_no_pointer_sign" == yes ; then + CFLAGS="$CFLAGS -Wno-pointer-sign" + fi +fi +AC_MSG_RESULT($CFLAGS) + + AC_PROG_CPP AC_PROG_INSTALL AC_PROG_RANLIB diff --git a/doc/bird.sgml b/doc/bird.sgml index b70f0345..6ad06909 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1039,7 +1039,7 @@ for each neighbor using the following configuration parameters: should not be advertised to any of its neighbors. If this option is enabled (which is by default), BIRD has such behavior automatically (it is evaluated when a route is - exported to the protocol just before the export filter). + exported to the BGP protocol just before the export filter). Otherwise, this integrated processing of well-known communities is disabled. In that case, similar behavior can be implemented in the export filter. Default: on. diff --git a/filter/config.Y b/filter/config.Y index fcbee714..1af5649c 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -172,7 +172,14 @@ function_params: function_body: decls '{' cmds '}' { - $$ = $3; + if ($1) { + /* Prepend instruction to clear local variables */ + $$ = f_new_inst(); + $$->code = P('c','v'); + $$->a1.p = $1; + $$->next = $3; + } else + $$ = $3; } ; diff --git a/filter/filter.c b/filter/filter.c index ec155ee6..de7a97bc 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -473,27 +473,10 @@ interpret(struct f_inst *what) case 's': ARG(v2, a2.p); sym = what->a1.p; - switch (res.type = v2.type) { - case T_VOID: runtime( "Can't assign void values" ); - case T_ENUM: - case T_BOOL: - case T_INT: - case T_PAIR: - case T_STRING: - case T_IP: - case T_PREFIX: - case T_PREFIX_SET: - case T_SET: - case T_PATH: - case T_PATH_MASK: - case T_CLIST: - if (sym->class != (SYM_VARIABLE | v2.type)) - runtime( "Assigning to variable of incompatible type" ); - * (struct f_val *) sym->def = v2; - break; - default: - bug( "Set to invalid type" ); - } + if ((sym->class != (SYM_VARIABLE | v2.type)) && + (v2.type != T_VOID)) + runtime( "Assigning to variable of incompatible type" ); + * (struct f_val *) sym->def = v2; break; /* some constants have value in a2, some in *a1.p, strange. */ @@ -605,42 +588,39 @@ interpret(struct f_inst *what) e = ea_find( (*f_tmp_attrs), what->a2.i ); if ((!e) && (f_flags & FF_FORCE_TMPATTR)) e = ea_find( (*f_rte)->attrs->eattrs, what->a2.i ); - + + if (!e) { + /* Undefined value */ + res.type = T_VOID; + break; + } + switch (what->aux & EAF_TYPE_MASK) { case EAF_TYPE_INT: - if (!e) { - res.type = T_VOID; - break; - } + case EAF_TYPE_ROUTER_ID: res.type = T_INT; res.val.i = e->u.data; break; + case EAF_TYPE_OPAQUE: + res.type = T_ENUM_EMPTY; + res.val.i = 0; + break; case EAF_TYPE_IP_ADDRESS: - if (!e) { - res.type = T_VOID; - break; - } res.type = T_IP; struct adata * ad = e->u.ptr; res.val.px.ip = * (ip_addr *) ad->data; break; case EAF_TYPE_AS_PATH: - if (!e) { - res.type = T_VOID; - break; - } res.type = T_PATH; res.val.ad = e->u.ptr; break; case EAF_TYPE_INT_SET: - if (!e) { - res.type = T_CLIST; - res.val.ad = adata_empty(f_pool); - break; - } res.type = T_CLIST; res.val.ad = e->u.ptr; break; + case EAF_TYPE_UNDEF: + res.type = T_VOID; + break; default: bug("Unknown type in e,a"); } @@ -659,10 +639,14 @@ interpret(struct f_inst *what) l->attrs[0].type = what->aux | EAF_ORIGINATED; switch (what->aux & EAF_TYPE_MASK) { case EAF_TYPE_INT: + case EAF_TYPE_ROUTER_ID: if (v1.type != T_INT) runtime( "Setting int attribute to non-int value" ); l->attrs[0].u.data = v1.val.i; break; + case EAF_TYPE_OPAQUE: + runtime( "Setting opaque attribute is not allowed" ); + break; case EAF_TYPE_IP_ADDRESS: if (v1.type != T_IP) runtime( "Setting ip attribute to non-ip value" ); @@ -765,6 +749,10 @@ interpret(struct f_inst *what) return res; res.type &= ~T_RETURN; break; + case P('c','v'): /* Clear local variables */ + for (sym = what->a1.p; sym != NULL; sym = sym->aux2) + ((struct f_val *) sym->def)->type = T_VOID; + break; case P('S','W'): ONEARG; { @@ -814,7 +802,11 @@ interpret(struct f_inst *what) case P('C','a'): /* Community list add or delete */ TWOARGS; - if (v1.type != T_CLIST) + + /* Replace undefined value with empty community list */ + if (v1.type == T_VOID) + v1.val.ad = adata_empty(f_pool); + else if (v1.type != T_CLIST) runtime("Can't add/delete to non-clist"); if (v2.type != T_PAIR) runtime("Can't add/delete non-pair"); @@ -943,6 +935,7 @@ i_same(struct f_inst *f1, struct f_inst *f2) return 0; f2->a2.p = f1->a2.p; break; + case P('c','v'): break; /* internal instruction */ case P('S','W'): ONEARG; if (!same_tree(f1->a2.p, f2->a2.p)) return 0; break; case P('i','M'): TWOARGS; break; case P('A','p'): TWOARGS; break; diff --git a/filter/test.conf b/filter/test.conf index 395699b0..8eeb5c35 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -75,7 +75,7 @@ clist l; p2 = prepend( p2, 1 ); print "Should be true: ", p2 ~ pm1, " ", p2, " ", pm1; - l = - empty -; +# l = - empty -; l = add( l, (1,2) ); l = add( l, (2,3) ); print "Community list (1,2) (2,3) ", l; @@ -124,6 +124,14 @@ function test_pxset(prefix set pxs) 11.0.0.0/10 ~ pxs, ",", 20.1.0.0/26 ~ pxs; } +function test_undef(int a) +int b; +{ + if a = 3 + then b = 4; + print "Defined: ", a, " ", b, " ", defined(b); +} + function __startup() int i; bool b; @@ -218,6 +226,10 @@ string s; print "1.2.3.4 = ", onetwo; + test_undef(2); + test_undef(3); + test_undef(2); + print "done"; quitbird; # print "*** FAIL: this is unreachable"; diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 94b105d7..b553475a 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -403,6 +403,7 @@ ea_format(eattr *e, byte *buf) bsprintf(buf, "%u", e->u.data); break; case EAF_TYPE_OPAQUE: + *buf = 0; for(i=0; i<ad->length; i++) { if (buf > end - 8) diff --git a/nest/rt-table.c b/nest/rt-table.c index 1860b1a1..802ea5fd 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -443,7 +443,12 @@ rte_recalculate(rtable *table, net *net, struct proto *p, struct proto *src, rte stats->imp_updates_ignored++; rte_trace_in(D_ROUTES, p, new, "ignored"); rte_free_quick(new); - old->lastmod = now; +#ifdef CONFIG_RIP + /* lastmod is used internally by RIP as the last time + when the route was received. */ + if (src->proto == &proto_rip) + old->lastmod = now; +#endif return; } *k = old->next; diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index c7527c97..e9d78b61 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -1140,7 +1140,7 @@ bad_no_log: return -1; } -int +void sk_open_unix(sock *s, char *name) { int fd; @@ -1149,15 +1149,13 @@ sk_open_unix(sock *s, char *name) fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) - die("sk_open_unix: socket: %m"); + ERR("socket"); s->fd = fd; if (err = sk_setup(s)) goto bad; unlink(name); - - if (strlen(name) >= sizeof(sa.sun_path)) - die("sk_open_unix: path too long"); + /* Path length checked in test_old_bird() */ sa.sun_family = AF_UNIX; strcpy(sa.sun_path, name); if (bind(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) < 0) @@ -1165,13 +1163,11 @@ sk_open_unix(sock *s, char *name) if (listen(fd, 8)) ERR("listen"); sk_insert(s); - return 0; + return; -bad: + bad: log(L_ERR "sk_open_unix: %s: %m", err); - close(fd); - s->fd = -1; - return -1; + die("Unable to create control socket %s", name); } static inline void reset_tx_buffer(sock *s) { s->ttx = s->tpos = s->tbuf; } @@ -1628,9 +1624,10 @@ test_old_bird(char *path) struct sockaddr_un sa; fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (fd < 0) die("Cannot create socket: %m"); + if (strlen(path) >= sizeof(sa.sun_path)) + die("Socket path too long"); bzero(&sa, sizeof(sa)); sa.sun_family = AF_UNIX; strcpy(sa.sun_path, path); diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c index 2245692c..e0e0d636 100644 --- a/sysdep/unix/main.c +++ b/sysdep/unix/main.c @@ -298,8 +298,7 @@ cli_init_unix(void) s->type = SK_UNIX_PASSIVE; s->rx_hook = cli_connect; s->rbsize = 1024; - if (sk_open_unix(s, path_control_socket) < 0) - die("Unable to create control socket %s", path_control_socket); + sk_open_unix(s, path_control_socket); } /* @@ -457,6 +456,9 @@ main(int argc, char **argv) rt_init(); if_init(); + if (!parse_and_exit) + cli_init_unix(); + protos_build(); proto_build(&proto_unix_kernel); proto_build(&proto_unix_iface); @@ -483,8 +485,6 @@ main(int argc, char **argv) signal_init(); - cli_init_unix(); - #ifdef LOCAL_DEBUG async_dump_flag = 1; #endif diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h index 0b179e00..4de74f28 100644 --- a/sysdep/unix/unix.h +++ b/sysdep/unix/unix.h @@ -49,7 +49,7 @@ void io_init(void); void io_loop(void); void fill_in_sockaddr(sockaddr *sa, ip_addr a, unsigned port); void get_sockaddr(sockaddr *sa, ip_addr *a, unsigned *port, int check); -int sk_open_unix(struct birdsock *s, char *name); +void sk_open_unix(struct birdsock *s, char *name); void *tracked_fopen(struct pool *, char *name, char *mode); void test_old_bird(char *path); |