summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2010-02-13 10:44:46 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2010-02-13 10:44:46 +0100
commit9db74169be76f658df2207d1ec99eac48fa36f5f (patch)
tree0221de7d14f9a27519d8a5bc3f0e58a37c6f0acf
parentc83876265eeae3591bfe90375503728e633cb807 (diff)
downloadbird-9db74169be76f658df2207d1ec99eac48fa36f5f.tar
bird-9db74169be76f658df2207d1ec99eac48fa36f5f.zip
Fixes protocol statistics for pipes.
-rw-r--r--nest/proto.c82
-rw-r--r--nest/protocol.h1
-rw-r--r--nest/rt-table.c53
-rw-r--r--proto/pipe/pipe.c7
4 files changed, 108 insertions, 35 deletions
diff --git a/nest/proto.c b/nest/proto.c
index c6b7e63..a7e4e0c 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -792,6 +792,67 @@ proto_state_name(struct proto *p)
}
static void
+proto_do_show_stats(struct proto *p)
+{
+ struct proto_stats *s = &p->stats;
+ cli_msg(-1006, " Routes: %u imported, %u exported, %u preferred",
+ s->imp_routes, s->exp_routes, s->pref_routes);
+ cli_msg(-1006, " Route change stats: received rejected filtered ignored accepted");
+ cli_msg(-1006, " Import updates: %10u %10u %10u %10u %10u",
+ s->imp_updates_received, s->imp_updates_invalid,
+ s->imp_updates_filtered, s->imp_updates_ignored,
+ s->imp_updates_accepted);
+ cli_msg(-1006, " Import withdraws: %10u %10u --- %10u %10u",
+ s->imp_withdraws_received, s->imp_withdraws_invalid,
+ s->imp_withdraws_ignored, s->imp_withdraws_accepted);
+ cli_msg(-1006, " Export updates: %10u %10u %10u --- %10u",
+ s->exp_updates_received, s->exp_updates_rejected,
+ s->exp_updates_filtered, s->exp_updates_accepted);
+ cli_msg(-1006, " Export withdraws: %10u --- --- --- %10u",
+ s->exp_withdraws_received, s->exp_withdraws_accepted);
+}
+
+static void
+proto_do_show_pipe_stats(struct proto *p)
+{
+ struct proto_stats *s1 = &p->stats;
+ struct proto_stats *s2 = pipe_get_peer_stats(p);
+
+ /*
+ * Pipe stats (as anything related to pipes) are a bit tricky. There
+ * are two sets of stats - s1 for routes going from the primary
+ * routing table to the secondary routing table ('exported' from the
+ * user point of view) and s2 for routes going in the other
+ * direction ('imported' from the user point of view).
+ *
+ * Each route going through a pipe is, technically, first exported
+ * to the pipe and then imported from that pipe and such operations
+ * are counted in one set of stats according to the direction of the
+ * route propagation. Filtering is done just in the first part
+ * (export). Therefore, we compose stats for one directon for one
+ * user direction from both import and export stats, skipping
+ * immediate and irrelevant steps (exp_updates_accepted,
+ * imp_updates_received, imp_updates_filtered, ...)
+ */
+
+ cli_msg(-1006, " Routes: %u imported, %u exported",
+ s2->imp_routes, s1->imp_routes);
+ cli_msg(-1006, " Route change stats: received rejected filtered ignored accepted");
+ cli_msg(-1006, " Import updates: %10u %10u %10u %10u %10u",
+ s2->exp_updates_received, s2->exp_updates_rejected + s2->imp_updates_invalid,
+ s2->exp_updates_filtered, s2->imp_updates_ignored, s2->imp_updates_accepted);
+ cli_msg(-1006, " Import withdraws: %10u %10u --- %10u %10u",
+ s2->exp_withdraws_received, s2->imp_withdraws_invalid,
+ s2->imp_withdraws_ignored, s2->imp_withdraws_accepted);
+ cli_msg(-1006, " Export updates: %10u %10u %10u %10u %10u",
+ s1->exp_updates_received, s1->exp_updates_rejected + s1->imp_updates_invalid,
+ s1->exp_updates_filtered, s1->imp_updates_ignored, s1->imp_updates_accepted);
+ cli_msg(-1006, " Export withdraws: %10u %10u --- %10u %10u",
+ s1->exp_withdraws_received, s1->imp_withdraws_invalid,
+ s1->imp_withdraws_ignored, s1->imp_withdraws_accepted);
+}
+
+static void
proto_do_show(struct proto *p, int verbose)
{
byte buf[256], tbuf[TM_DATETIME_BUFFER_SIZE];
@@ -817,21 +878,12 @@ proto_do_show(struct proto *p, int verbose)
if (p->proto_state != PS_DOWN)
{
- cli_msg(-1006, " Routes: %u imported, %u exported, %u preferred",
- p->stats.imp_routes, p->stats.exp_routes, p->stats.pref_routes);
- cli_msg(-1006, " Route change stats: received rejected filtered ignored accepted");
- cli_msg(-1006, " Import updates: %10u %10u %10u %10u %10u",
- p->stats.imp_updates_received, p->stats.imp_updates_invalid,
- p->stats.imp_updates_filtered, p->stats.imp_updates_ignored,
- p->stats.imp_updates_accepted);
- cli_msg(-1006, " Import withdraws: %10u %10u --- %10u %10u",
- p->stats.imp_withdraws_received, p->stats.imp_withdraws_invalid,
- p->stats.imp_withdraws_ignored, p->stats.imp_withdraws_accepted);
- cli_msg(-1006, " Export updates: %10u %10u %10u --- %10u",
- p->stats.exp_updates_received, p->stats.exp_updates_rejected,
- p->stats.exp_updates_filtered, p->stats.exp_updates_accepted);
- cli_msg(-1006, " Export withdraws: %10u --- --- --- %10u",
- p->stats.exp_withdraws_received, p->stats.exp_withdraws_accepted);
+#ifdef CONFIG_PIPE
+ if (proto_is_pipe(p))
+ proto_do_show_pipe_stats(p);
+ else
+#endif
+ proto_do_show_stats(p);
}
cli_msg(-1006, "");
diff --git a/nest/protocol.h b/nest/protocol.h
index 99d8dc8..876427a 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -344,6 +344,7 @@ static inline int proto_is_pipe(struct proto *p)
{ return p->proto == &proto_pipe; }
struct rtable *pipe_get_peer_table(struct proto *p);
+struct proto_stats *pipe_get_peer_stats(struct proto *p);
#endif
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();
diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c
index d9df03b..879135d 100644
--- a/proto/pipe/pipe.c
+++ b/proto/pipe/pipe.c
@@ -234,6 +234,13 @@ pipe_get_peer_table(struct proto *P)
return p->peer;
}
+struct proto_stats *
+pipe_get_peer_stats(struct proto *P)
+{
+ struct pipe_proto *p = (struct pipe_proto *) P;
+ return &p->phantom->p.stats;
+}
+
struct protocol proto_pipe = {
name: "Pipe",
template: "pipe%d",