From 024e633c16cf21ae94d7e023e057e59080f92175 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Tue, 11 Aug 2009 10:54:50 +0200 Subject: Fixes bug that caused losing of some routes. When update changes preferred route in such a way that it ceased to be preferred, the new route was linked to wrong place and lost. --- nest/rt-table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nest') diff --git a/nest/rt-table.c b/nest/rt-table.c index fb2feac..7213836 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -464,8 +464,8 @@ rte_recalculate(rtable *table, net *net, struct proto *p, struct proto *src, rte } if (new) /* Link in the new non-optimal route */ { - new->next = old_best->next; - old_best->next = new; + new->next = net->routes->next; + net->routes->next = new; rte_trace_in(D_ROUTES, p, new, "added"); } else if (old && (p->debug & D_ROUTES)) -- cgit v1.2.3 From ac07aacd2cdb5cf69a3bfdbc0e078cb0ae96c0db Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Tue, 11 Aug 2009 11:03:37 +0200 Subject: Replace assert with log. Although it is true unless there is a bug in BIRD, this assert is not needed (code below does not require that assumption), so we should not crash. --- nest/proto.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'nest') diff --git a/nest/proto.c b/nest/proto.c index 2af077b..d079213 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -515,7 +515,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); -- cgit v1.2.3 From c0973621bc1e06cb6176dc2dfd97bec637861edd Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Tue, 11 Aug 2009 15:49:56 +0200 Subject: Fixes another bug in rte_recalculate(). Previous bugfix revealed another hidden bug here. --- nest/rt-table.c | 104 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 37 deletions(-) (limited to 'nest') diff --git a/nest/rt-table.c b/nest/rt-table.c index 7213836..87bf0dc 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 = net->routes->next; - net->routes->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) -- cgit v1.2.3 From 87d7fd9725ded186f6fa331d68a1e9df5d1982cf Mon Sep 17 00:00:00 2001 From: Ondrej Filip Date: Sun, 16 Aug 2009 22:36:41 +0200 Subject: Bugfix - each protocol can be compiled separately. --- nest/config.Y | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'nest') diff --git a/nest/config.Y b/nest/config.Y index dc31224..ad45a0d 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) @@ -293,6 +293,7 @@ password_item_params: ; + /* Core commands */ CF_CLI_HELP(SHOW, ..., [[Show status information]]) -- cgit v1.2.3 From fee78355b480294f28c3c6814953297dca92d4a0 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Fri, 21 Aug 2009 09:31:35 +0200 Subject: Fixes bug in eattr binary search. --- nest/rt-attr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nest') diff --git a/nest/rt-attr.c b/nest/rt-attr.c index de63198..9d78ce0 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; -- cgit v1.2.3 From 949bd34e81ee99370decdabefa51c9c11ffe915b Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Tue, 25 Aug 2009 19:01:37 +0200 Subject: Fixes bug related to AS2->AS4 conversion. --- nest/a-path.c | 6 ++++++ nest/attrs.h | 1 + 2 files changed, 7 insertions(+) (limited to 'nest') diff --git a/nest/a-path.c b/nest/a-path.c index dba214d..0a4bf82 100644 --- a/nest/a-path.c +++ b/nest/a-path.c @@ -188,6 +188,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; diff --git a/nest/attrs.h b/nest/attrs.h index b838ce9..eee6b37 100644 --- a/nest/attrs.h +++ b/nest/attrs.h @@ -28,6 +28,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); -- cgit v1.2.3 From 05198c12f48c9d4a65ee6d1d4117bd8067a71131 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Thu, 27 Aug 2009 19:01:04 +0200 Subject: Some cleanups. --- nest/a-path.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'nest') diff --git a/nest/a-path.c b/nest/a-path.c index 0a4bf82..19d61f0 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. @@ -304,7 +305,7 @@ parse_path(struct adata *path, struct pm_pos *pos) u8 *p = path->data; u8 *q = p + path->length; struct pm_pos *opos = pos; - int i, j, len; + int i, len; while (p < q) -- cgit v1.2.3 From f4c6ca8c9c7ca7c0d481e6059396beed6adc768d Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Thu, 17 Sep 2009 13:35:37 +0200 Subject: Fixes preference bounds. --- nest/config.Y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nest') diff --git a/nest/config.Y b/nest/config.Y index ad45a0d..a2c44ab 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -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; } -- cgit v1.2.3 From 46eb80d5d50a2b284cae19444149d57d857a8e02 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Thu, 17 Sep 2009 17:52:36 +0200 Subject: Fixes headers for uintptr_t (and build on NetBSD). --- nest/attrs.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'nest') diff --git a/nest/attrs.h b/nest/attrs.h index eee6b37..16fb35a 100644 --- a/nest/attrs.h +++ b/nest/attrs.h @@ -9,6 +9,8 @@ #ifndef _BIRD_ATTRS_H_ #define _BIRD_ATTRS_H_ +#include + /* a-path.c */ #define AS_PATH_SET 1 /* Types of path segments */ -- cgit v1.2.3 From 52b9b2a1786140c38af03de570b0cc96c835c1d3 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Mon, 12 Oct 2009 20:44:58 +0200 Subject: Rename as_path_get_last/as_path_get_first to be consistent. --- nest/a-path.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'nest') diff --git a/nest/a-path.c b/nest/a-path.c index 19d61f0..c804619 100644 --- a/nest/a-path.c +++ b/nest/a-path.c @@ -213,7 +213,7 @@ as_path_getlen_int(struct adata *path, int bs) } 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; @@ -229,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; @@ -246,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; -- cgit v1.2.3 From 4cdd078453d585ac97a183ea1f3951d85f1b8784 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Mon, 12 Oct 2009 23:31:42 +0200 Subject: Implements protocol-specific router id and updates documentation. --- nest/config.Y | 1 + nest/proto.c | 1 + nest/protocol.h | 8 ++++++++ 3 files changed, 10 insertions(+) (limited to 'nest') diff --git a/nest/config.Y b/nest/config.Y index a2c44ab..4721112 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -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: diff --git a/nest/proto.c b/nest/proto.c index d079213..7bb1286 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) diff --git a/nest/protocol.h b/nest/protocol.h index 0f9d59d..484df84 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; /* -- cgit v1.2.3