]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
TMP: compiles and run (doesn't read max generation)
authorVojtech Vilimek <vojtech.vilimek@nic.cz>
Tue, 19 Jul 2022 08:21:43 +0000 (10:21 +0200)
committerVojtech Vilimek <vojtech.vilimek@nic.cz>
Tue, 19 Jul 2022 08:21:43 +0000 (10:21 +0200)
nest/protocol.h
proto/stats/config.Y
proto/stats/stats.c
proto/stats/stats.h

index d4c38b907c59ccc74e05f9227d53a3203c3f3de5..a2511eb8c22aabe21039e69db8a80144644c1948 100644 (file)
@@ -443,6 +443,7 @@ struct channel_class {
 };
 
 extern struct channel_class channel_bgp;
+extern struct channel_class channel_stats;
 
 struct channel_config {
   node n;
index e66f18d13f807a2f48dfea91a2641d1d71128ae1..b32ea773a2074b9fd13d990ad6d1cb38d1b654d9 100644 (file)
@@ -15,7 +15,7 @@ CF_HDR
 CF_DEFINES
 
 /* old: #define PIPE_CFG ((struct pipe_config *) this_proto) */
-#define STATS_CFG ((struct stats_config *) this_proto) 
+#define STATS_CC ((struct stats_channel_config *) this_channel)
 
 CF_DECLS
 
@@ -31,16 +31,36 @@ proto: stats_proto '}' { this_channel = NULL; }  ;
 stats_proto_start: proto_start STATS
 {
   this_proto = proto_config_new(&proto_stats, $1);
-  STATS_CFG->max_generation = 16;
 }
 
 proto_name ;
 
-stats_proto_channel: stats_channel_start channel_opt_list channel_end ;
+stats_channel_opt_list:
+    /* empty */
+  | '{' stats_opts '}'
+  ;
+
+
+channel_max_gen:
+  MAX GENERATION expr {
+    if ($3 > 254) cf_error("Max generation must be in range 0..254, got %u", $3);
+    STATS_CC->max_generation = $3;
+  }
+  ;
+
+stats_opts:
+    /* empty */
+  | stats_opts channel_item ';'
+  | stats_opts channel_max_gen ';'
+  ;
+     
+stats_proto_channel: stats_channel_start stats_channel_opt_list channel_end ;
+/* stats_proto_channel: stats_channel_start stats_max_gen channel_opt_list channel_end ; */
 
 stats_channel_start: net_type symbol
 {
-  $$ = this_channel = channel_config_get(NULL, $2->name, $1, this_proto);
+  this_channel = channel_config_get(&channel_stats, $2->name, $1, this_proto);
+  STATS_CC->max_generation = 16;
 }
 
 stats_proto:
index ab0b664af36259008afaa18145802d1cebdbe00b..713b68372d76b38f72730d249004093cc4b7ea19 100644 (file)
 static void
 stats_rt_notify(struct proto *P, struct channel *src_ch, const net_addr *n, rte *new, const rte *old)
 {
-  struct stats_proto *p = (void *) P;
-  struct stats_config *cf = (void *) P->cf;
-  log(L_INFO "stats_rf_notify()");
+  struct stats_channel *ch = src_ch;
+  log(L_INFO "stats_rt_notify() %u", ch->max_generation);
 
   if (old)
   {
-    p->counters[old->generation]--;
-    log(L_INFO "counter %u decreased", old->generation);
+    if (old->generation < ch->max_generation)
+    {
+      ch->counters[old->generation]--;
+      log(L_INFO "channel %s counter %u was decreased", src_ch->name, old->generation);
+    }
+    else
+    {
+      log(L_WARN "Stats: Maximum generation reached in channel %s, route is dropped.",
+       src_ch->name
+      );
+    }
   }
 
   if (new)
   {
-    p->counters[new->generation]++;
-    log(L_INFO "counter %u increased", new->generation);
-  }
+    if (new->generation < ch->max_generation)
+    {
+      ch->counters[new->generation]++;
+      log(L_INFO "channel %s counter %u was increased", src_ch->name, new->generation);
+    }
+    else
+    {
+      log(L_WARN "Stats: Maximum generation reached in channel %s, route is dropped.",
+       src_ch->name
+      );
+    }
+  }  
 }
 
 static int
@@ -72,6 +89,7 @@ stats_configure_channels(struct proto *P, struct proto_config *CF)
 {
   struct stats_proto *p = (void *) P;
   struct stats_config *cf = (void *) CF;
+  log(L_INFO "stats_configure_channels()");
 
   struct channel_config *cc;
   WALK_LIST(cc, CF->channels)
@@ -115,9 +133,7 @@ static int
 stats_start(struct proto *P) 
 {
   struct stats_proto *p = (struct stats_proto *) P;
-  log(L_INFO "stats_start() ");
-
-  p->counters = (u32 *) mb_allocz(p->p.pool, 256 * sizeof(u32));
+  log(L_INFO "stats_start()");
 
   return PS_UP;
 }
@@ -159,27 +175,49 @@ stats_copy_config(struct proto_config *dest UNUSED, struct proto_config *src UNU
   /* Just a shallow copy, not many items here */
 }
 
+/* NO NEED TO PRINT ANYTHING BEFORE protocols header
+
 static void
 stats_get_status(struct proto *P, byte *buf)
 {
   struct stats_proto *p = (void *) P;
+  
+  cli_msg(-1006, " another super informative message "); 
 }
+*/
 
 static void
 stats_show_proto_info(struct proto *P)
 {
   struct stats_proto *p = (void *) P;
+  log(L_INFO "stats_show_proto_info() ");
+
+  u32 *a = mb_alloc(p->p.pool, 256 * sizeof(u32));
 
-  cli_msg(-1006, "  Counters contents  ");
-  for (int i = 0; i < 64; i++) 
+  struct stats_channel *sc;
+  WALK_LIST(sc, p->p.channels)
   {
-    cli_msg(-1006, "%3u: %10u | %3u: %10u | %3u: %10u | %3u: %10u",
-       i       , *(p->counters + i),
-      (i + 64 ), *(p->counters + i + 64),
-      (i + 128), *(p->counters + i + 128),
-      (i + 192), *(p->counters + i + 192)
-    );
-  }   
+    for (uint i = 0; i < 256; i++)
+    {
+      *(a + i) = 0;
+    }
+  
+    u8 len = 0;
+    for (u8 i = 0; i < sc->max_generation; i++)
+      if (*(sc->counters + i) != 0)
+      {
+       log(L_INFO "found non-zero %u in counter %u", sc->counters[i], i);
+       *(a + len) = i;
+       len++;
+      }
+
+    cli_msg(-1006, "  Channel %s counter contents  ", sc->c.name);
+
+    for (u8 i = 0; i < len; i ++)
+      cli_msg(-1006, " %3u: %10u ", i, *(a + i));
+  }
+
+  mb_free(a);
 }
 
 void
@@ -187,9 +225,42 @@ stats_update_debug(struct proto *P)
 {
   struct stats_proto *p = (void *) P;
 
-  p->c->debug = p->p.debug;
+  //p->c->debug = p->p.debug;
 }
 
+static int
+stats_channel_start(struct channel *C)
+{
+  struct stats_proto *p = (void *) C->proto;
+  struct stats_channel *c = (void *) C;
+  log(L_INFO "stats_channel_start() %s", C->name);
+
+  c->pool = p->p.pool;
+
+  c->counters = mb_allocz(c->pool, c->max_generation * sizeof(u32));
+
+  return 0;
+}
+
+static void
+stats_channel_shutdown(struct channel *C)
+{
+  struct stats_channel *c = (void *) C;
+  log(L_INFO "stats_channel_shutdown() %s", C->name);
+
+  mb_free(c->counters);
+  
+  c->max_generation = 0;
+  c->counters = NULL;
+  c->pool = NULL;
+}
+
+struct channel_class channel_stats = {
+  .channel_size =      sizeof(struct stats_channel),
+  .config_size =       sizeof(struct stats_channel_config),
+  .start =             stats_channel_start,
+  .shutdown =          stats_channel_shutdown,
+};
 
 struct protocol proto_stats = {
   .name =              "Stats",
@@ -201,7 +272,7 @@ struct protocol proto_stats = {
   .start =             stats_start,
   .reconfigure =       stats_reconfigure,
   .copy_config =       stats_copy_config,
-  .get_status =        stats_get_status,
+  //.get_status =      stats_get_status,
   .show_proto_info =   stats_show_proto_info
 };
 
index 552a6d8234b6f1c9c68ec381f73d9ce84366edf2..12a12c29f3845f46425e580244672aa052e69d77 100644 (file)
 #ifndef _BIRD_STATS_H_
 #define _BIRD_STATS_H_
 
+struct stats_channel;
+
 struct stats_config {
   struct proto_config c;
-  u8 max_generation;
 };
 
 struct stats_proto {
   struct proto p;
-  struct channel *c;
+  struct stats_channel *c;
   struct tbf rl_gen;
+};
+
+struct stats_channel {
+  struct channel c;
+  pool *pool;
+  u8 max_generation;
   u32 *counters;
 };
 
+struct stats_channel_config {
+  struct channel_config c;
+  u8 max_generation;
+};
+
 #endif