]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Fixes protocol statistics for pipes.
authorOndrej Zajicek <santiago@crfreenet.org>
Sat, 13 Feb 2010 09:44:46 +0000 (10:44 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Sat, 13 Feb 2010 09:44:46 +0000 (10:44 +0100)
nest/proto.c
nest/protocol.h
nest/rt-table.c
proto/pipe/pipe.c

index c6b7e63c90ddc3f7452f795ceb78ec921031db29..a7e4e0c9dfc1650211b6b7b148444a4a8618661a 100644 (file)
@@ -791,6 +791,67 @@ proto_state_name(struct proto *p)
 #undef 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)
 {
@@ -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, "");
index 99d8dc80e63f46dcde56fb114b3f9aa22bece181..876427ab8889e7823831cf3012e70f0c3085078d 100644 (file)
@@ -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
 
index fee571897478af94c3358ade3424137e0217571d..c9e421e9428f3ffd19e4ccace0ac79c0679d848b 100644 (file)
@@ -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();
index d9df03bad2314fa703a8cf532fd124743735050b..879135d14d399aaf2861df07c0bfe9c44aba1bc7 100644 (file)
@@ -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",