From c83876265eeae3591bfe90375503728e633cb807 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Thu, 11 Feb 2010 22:27:06 +0100 Subject: Fixes a tricky bug in the pipe protocol. When uncofiguring the pipe and the peer table, the peer table was unlocked when pipe protocol state changed to down/flushing and not to down/hungry. This leads to the removal of the peer table before the routes from the pipe were flushed. The fix leads to adding some pipe-specific hacks to the nest, but this seems inevitable. --- nest/rt-table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nest/rt-table.c') diff --git a/nest/rt-table.c b/nest/rt-table.c index 413675c..fee5718 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -642,7 +642,7 @@ rte_update(rtable *table, net *net, struct proto *p, struct proto *src, rte *new /* Do not filter routes going through the pipe, they are filtered in the export filter only. */ #ifdef CONFIG_PIPE - if (p->proto == &proto_pipe) + if (proto_is_pipe(p)) filter = FILTER_ACCEPT; #endif -- cgit v1.2.3 From 9db74169be76f658df2207d1ec99eac48fa36f5f Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Sat, 13 Feb 2010 10:44:46 +0100 Subject: Fixes protocol statistics for pipes. --- nest/rt-table.c | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) (limited to 'nest/rt-table.c') diff --git a/nest/rt-table.c b/nest/rt-table.c index fee5718..c9e421e 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -161,6 +161,7 @@ static inline void do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, ea_list *tmpa, int class, int refeed) { struct proto *p = a->proto; + struct proto_stats *stats = &p->stats; rte *new0 = new; rte *old0 = old; int ok; @@ -169,18 +170,18 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, if (new) { - p->stats.exp_updates_received++; + stats->exp_updates_received++; char *drop_reason = NULL; if ((class & IADDR_SCOPE_MASK) < p->min_scope) { - p->stats.exp_updates_rejected++; + stats->exp_updates_rejected++; drop_reason = "out of scope"; fast_exit_hack = 1; } else if ((ok = p->import_control ? p->import_control(p, &new, &tmpa, rte_update_pool) : 0) < 0) { - p->stats.exp_updates_rejected++; + stats->exp_updates_rejected++; drop_reason = "rejected by protocol"; } else if (ok) @@ -188,7 +189,7 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, else if (p->out_filter == FILTER_REJECT || p->out_filter && f_run(p->out_filter, &new, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT) { - p->stats.exp_updates_filtered++; + stats->exp_updates_filtered++; drop_reason = "filtered out"; } if (drop_reason) @@ -200,7 +201,7 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, } } else - p->stats.exp_withdraws_received++; + stats->exp_withdraws_received++; /* Hack: This is here to prevent 'spurious withdraws' for loopback addresses during reload. */ @@ -249,16 +250,16 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, return; if (new) - p->stats.exp_updates_accepted++; + stats->exp_updates_accepted++; else - p->stats.exp_withdraws_accepted++; + stats->exp_withdraws_accepted++; /* Hack: We do not decrease exp_routes during refeed, we instead reset exp_routes at the start of refeed. */ if (new) - p->stats.exp_routes++; + stats->exp_routes++; if (old && !refeed) - p->stats.exp_routes--; + stats->exp_routes--; if (p->debug & D_ROUTES) { @@ -416,10 +417,16 @@ rte_same(rte *x, rte *y) static void rte_recalculate(rtable *table, net *net, struct proto *p, struct proto *src, rte *new, ea_list *tmpa) { + struct proto_stats *stats = &p->stats; rte *old_best = net->routes; rte *old = NULL; rte **k, *r, *s; +#ifdef CONFIG_PIPE + if (proto_is_pipe(p) && (p->table == table)) + stats = pipe_get_peer_stats(p); +#endif + k = &net->routes; /* Find and remove original route from the same protocol */ while (old = *k) { @@ -448,7 +455,7 @@ rte_recalculate(rtable *table, net *net, struct proto *p, struct proto *src, rte if (new && rte_same(old, new)) { /* No changes, ignore the new route */ - p->stats.imp_updates_ignored++; + stats->imp_updates_ignored++; rte_trace_in(D_ROUTES, p, new, "ignored"); rte_free_quick(new); old->lastmod = now; @@ -462,19 +469,19 @@ rte_recalculate(rtable *table, net *net, struct proto *p, struct proto *src, rte if (!old && !new) { - p->stats.imp_withdraws_ignored++; + stats->imp_withdraws_ignored++; return; } if (new) - p->stats.imp_updates_accepted++; + stats->imp_updates_accepted++; else - p->stats.imp_withdraws_accepted++; + stats->imp_withdraws_accepted++; if (new) - p->stats.imp_routes++; + stats->imp_routes++; if (old) - p->stats.imp_routes--; + stats->imp_routes--; rte_announce(table, RA_ANY, net, new, old, tmpa); @@ -632,6 +639,12 @@ void rte_update(rtable *table, net *net, struct proto *p, struct proto *src, rte *new) { ea_list *tmpa = NULL; + struct proto_stats *stats = &p->stats; + +#ifdef CONFIG_PIPE + if (proto_is_pipe(p) && (p->table == table)) + stats = pipe_get_peer_stats(p); +#endif rte_update_lock(); if (new) @@ -646,16 +659,16 @@ rte_update(rtable *table, net *net, struct proto *p, struct proto *src, rte *new filter = FILTER_ACCEPT; #endif - p->stats.imp_updates_received++; + stats->imp_updates_received++; if (!rte_validate(new)) { rte_trace_in(D_FILTERS, p, new, "invalid"); - p->stats.imp_updates_invalid++; + stats->imp_updates_invalid++; goto drop; } if (filter == FILTER_REJECT) { - p->stats.imp_updates_filtered++; + stats->imp_updates_filtered++; rte_trace_in(D_FILTERS, p, new, "filtered out"); goto drop; } @@ -667,7 +680,7 @@ rte_update(rtable *table, net *net, struct proto *p, struct proto *src, rte *new int fr = f_run(filter, &new, &tmpa, rte_update_pool, 0); if (fr > F_ACCEPT) { - p->stats.imp_updates_filtered++; + stats->imp_updates_filtered++; rte_trace_in(D_FILTERS, p, new, "filtered out"); goto drop; } @@ -679,7 +692,7 @@ rte_update(rtable *table, net *net, struct proto *p, struct proto *src, rte *new new->flags |= REF_COW; } else - p->stats.imp_withdraws_received++; + stats->imp_withdraws_received++; rte_recalculate(table, net, p, src, new, tmpa); rte_update_unlock(); -- cgit v1.2.3 From dca75fd7c207f0bfc627cb6b74a484da3b27e05f Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Sat, 13 Feb 2010 12:26:26 +0100 Subject: Removes phantom protocol from the pipe design. It seems that by adding one pipe-specific exception to route announcement code and by adding one argument to rt_notify() callback i could completely eliminate the need for the phantom protocol instance and therefore make the code more straightforward. It will also fix some minor bugs (like ignoring debug flag changes from the command line). --- nest/rt-table.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'nest/rt-table.c') diff --git a/nest/rt-table.c b/nest/rt-table.c index c9e421e..72a1cb0 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -161,6 +161,7 @@ static inline void do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, ea_list *tmpa, int class, int refeed) { struct proto *p = a->proto; + struct filter *filter = p->out_filter; struct proto_stats *stats = &p->stats; rte *new0 = new; rte *old0 = old; @@ -168,6 +169,15 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, int fast_exit_hack = 0; +#ifdef CONFIG_PIPE + /* The secondary direction of the pipe */ + if (proto_is_pipe(p) && (p->table != a->table)) + { + filter = p->in_filter; + stats = pipe_get_peer_stats(p); + } +#endif + if (new) { stats->exp_updates_received++; @@ -186,8 +196,8 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, } else if (ok) rte_trace_out(D_FILTERS, p, new, "forced accept by protocol"); - else if (p->out_filter == FILTER_REJECT || - p->out_filter && f_run(p->out_filter, &new, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT) + else if (filter == FILTER_REJECT || + filter && f_run(filter, &new, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT) { stats->exp_updates_filtered++; drop_reason = "filtered out"; @@ -230,13 +240,13 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, if (old && !refeed) { - if (p->out_filter == FILTER_REJECT) + if (filter == FILTER_REJECT) old = NULL; else { ea_list *tmpb = p->make_tmp_attrs ? p->make_tmp_attrs(old, rte_update_pool) : NULL; ok = p->import_control ? p->import_control(p, &old, &tmpb, rte_update_pool) : 0; - if (ok < 0 || (!ok && p->out_filter && f_run(p->out_filter, &old, &tmpb, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT)) + if (ok < 0 || (!ok && filter && f_run(filter, &old, &tmpb, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT)) { if (old != old0) rte_free(old); @@ -271,18 +281,18 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, rte_trace_out(D_ROUTES, p, old, "removed"); } if (!new) - p->rt_notify(p, net, NULL, old, NULL); + p->rt_notify(p, a->table, net, NULL, old, NULL); else if (tmpa) { ea_list *t = tmpa; while (t->next) t = t->next; t->next = new->attrs->eattrs; - p->rt_notify(p, net, new, old, tmpa); + p->rt_notify(p, a->table, net, new, old, tmpa); t->next = NULL; } else - p->rt_notify(p, net, new, old, new->attrs->eattrs); + p->rt_notify(p, a->table, net, new, old, new->attrs->eattrs); if (new && new != new0) /* Discard temporary rte's */ rte_free(new); if (old && old != old0) -- cgit v1.2.3 From e81b440f6878605edd19ed62441648ac71260881 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Sun, 21 Feb 2010 14:34:53 +0100 Subject: Fix configure to enable warnings and fix most of them. --- nest/rt-table.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'nest/rt-table.c') diff --git a/nest/rt-table.c b/nest/rt-table.c index 72a1cb0..41ecf64 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -158,7 +158,7 @@ rte_trace_out(unsigned int flag, struct proto *p, rte *e, char *msg) } static inline void -do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, ea_list *tmpa, int class, int refeed) +do_rte_announce(struct announce_hook *a, int type UNUSED, net *net, rte *new, rte *old, ea_list *tmpa, int class, int refeed) { struct proto *p = a->proto; struct filter *filter = p->out_filter; @@ -196,8 +196,8 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, } else if (ok) rte_trace_out(D_FILTERS, p, new, "forced accept by protocol"); - else if (filter == FILTER_REJECT || - filter && f_run(filter, &new, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT) + else if ((filter == FILTER_REJECT) || + (filter && f_run(filter, &new, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT)) { stats->exp_updates_filtered++; drop_reason = "filtered out"; @@ -329,7 +329,7 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, * the protocol gets called. */ static void -rte_announce(rtable *tab, int type, net *net, rte *new, rte *old, ea_list *tmpa) +rte_announce(rtable *tab, unsigned type, net *net, rte *new, rte *old, ea_list *tmpa) { struct announce_hook *a; int class = ipa_classify(net->n.prefix); @@ -1203,8 +1203,8 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d) 'configure soft' command may change the export filter and do not update routes */ - if (p1->out_filter == FILTER_REJECT || - p1->out_filter && f_run(p1->out_filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT) + if ((p1->out_filter == FILTER_REJECT) || + (p1->out_filter && f_run(p1->out_filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT)) ok = 0; } } -- cgit v1.2.3 From ff2857b03db854f99902766ad842aaa5fa29ec3c Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Fri, 26 Feb 2010 10:55:58 +0100 Subject: Many changes in (mainly) kernel syncers. - BSD kernel syncer is now self-conscious and can learn alien routes - important bugfix in BSD kernel syncer (crash after protocol restart) - many minor changes and bugfixes in kernel syncers and neighbor cache - direct protocol does not generate host and link local routes - min_scope check is removed, all routes have SCOPE_UNIVERSE by default - also fixes some remaining compiler warnings --- nest/rt-table.c | 52 ++++++++++++---------------------------------------- 1 file changed, 12 insertions(+), 40 deletions(-) (limited to 'nest/rt-table.c') diff --git a/nest/rt-table.c b/nest/rt-table.c index 41ecf64..1860b1a 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -158,7 +158,7 @@ rte_trace_out(unsigned int flag, struct proto *p, rte *e, char *msg) } static inline void -do_rte_announce(struct announce_hook *a, int type UNUSED, net *net, rte *new, rte *old, ea_list *tmpa, int class, int refeed) +do_rte_announce(struct announce_hook *a, int type UNUSED, net *net, rte *new, rte *old, ea_list *tmpa, int refeed) { struct proto *p = a->proto; struct filter *filter = p->out_filter; @@ -183,13 +183,7 @@ do_rte_announce(struct announce_hook *a, int type UNUSED, net *net, rte *new, rt stats->exp_updates_received++; char *drop_reason = NULL; - if ((class & IADDR_SCOPE_MASK) < p->min_scope) - { - stats->exp_updates_rejected++; - drop_reason = "out of scope"; - fast_exit_hack = 1; - } - else if ((ok = p->import_control ? p->import_control(p, &new, &tmpa, rte_update_pool) : 0) < 0) + if ((ok = p->import_control ? p->import_control(p, &new, &tmpa, rte_update_pool) : 0) < 0) { stats->exp_updates_rejected++; drop_reason = "rejected by protocol"; @@ -332,7 +326,6 @@ static void rte_announce(rtable *tab, unsigned type, net *net, rte *new, rte *old, ea_list *tmpa) { struct announce_hook *a; - int class = ipa_classify(net->n.prefix); if (type == RA_OPTIMAL) { @@ -346,7 +339,7 @@ rte_announce(rtable *tab, unsigned type, net *net, rte *new, rte *old, ea_list * { ASSERT(a->proto->core_state == FS_HAPPY || a->proto->core_state == FS_FEEDING); if (a->proto->accept_ra_types == type) - do_rte_announce(a, type, net, new, old, tmpa, class, 0); + do_rte_announce(a, type, net, new, old, tmpa, 0); } } @@ -362,33 +355,15 @@ rte_validate(rte *e) n->n.prefix, n->n.pxlen, e->sender->name); return 0; } - if (n->n.pxlen) + + c = ipa_classify_net(n->n.prefix); + if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK)) { - c = ipa_classify(n->n.prefix); - if (c < 0 || !(c & IADDR_HOST)) - { - if (!ipa_nonzero(n->n.prefix)) - { - /* Various default routes */ -#ifdef IPV6 - if (n->n.pxlen == 96) -#else - if (n->n.pxlen <= 1) -#endif - return 1; - } - log(L_WARN "Ignoring bogus route %I/%d received via %s", - n->n.prefix, n->n.pxlen, e->sender->name); - return 0; - } - if ((c & IADDR_SCOPE_MASK) < e->sender->min_scope) - { - log(L_WARN "Ignoring %s scope route %I/%d received from %I via %s", - ip_scope_text(c & IADDR_SCOPE_MASK), - n->n.prefix, n->n.pxlen, e->attrs->from, e->sender->name); - return 0; - } + log(L_WARN "Ignoring bogus route %I/%d received via %s", + n->n.prefix, n->n.pxlen, e->sender->name); + return 0; } + return 1; } @@ -1018,7 +993,7 @@ do_feed_baby(struct proto *p, int type, struct announce_hook *h, net *n, rte *e) rte_update_lock(); tmpa = q->make_tmp_attrs ? q->make_tmp_attrs(e, rte_update_pool) : NULL; - do_rte_announce(h, type, n, e, p->refeeding ? e : NULL, tmpa, ipa_classify(n->n.prefix), p->refeeding); + do_rte_announce(h, type, n, e, p->refeeding ? e : NULL, tmpa, p->refeeding); rte_update_unlock(); } @@ -1190,11 +1165,8 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d) if (p2 && p2 != p0) ok = 0; if (ok && d->export_mode) { - int class = ipa_classify(n->n.prefix); int ic; - if ((class & IADDR_SCOPE_MASK) < p1->min_scope) - ok = 0; - else if ((ic = p1->import_control ? p1->import_control(p1, &e, &tmpa, rte_update_pool) : 0) < 0) + if ((ic = p1->import_control ? p1->import_control(p1, &e, &tmpa, rte_update_pool) : 0) < 0) ok = 0; else if (!ic && d->export_mode > 1) { -- cgit v1.2.3