summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--aclocal.m413
-rw-r--r--conf/conf.c2
-rw-r--r--configure.in17
-rw-r--r--doc/bird.sgml2
-rw-r--r--filter/config.Y9
-rw-r--r--filter/filter.c73
-rw-r--r--filter/test.conf14
-rw-r--r--nest/rt-attr.c1
-rw-r--r--nest/rt-table.c7
-rw-r--r--sysdep/unix/io.c19
-rw-r--r--sysdep/unix/main.c8
-rw-r--r--sysdep/unix/unix.h2
12 files changed, 104 insertions, 63 deletions
diff --git a/aclocal.m4 b/aclocal.m4
index c5af7895..e98a4139 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -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);