]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
TMP compiles but doesn't work
authorVojtech Vilimek <vojtech.vilimek@nic.cz>
Wed, 27 Jul 2022 11:21:47 +0000 (13:21 +0200)
committerVojtech Vilimek <vojtech.vilimek@nic.cz>
Wed, 27 Jul 2022 11:21:47 +0000 (13:21 +0200)
conf/conf.h
filter/config.Y
filter/f-inst.c
filter/filter.c
proto/stats/config.Y
proto/stats/stats-pub.h [new file with mode: 0644]
proto/stats/stats.c
proto/stats/stats.h

index d193155bd890b0b2d14d79bf44f9b74ff352013b..6907666b7182c6bea175005cd4eb380ecc41d4f9 100644 (file)
@@ -109,6 +109,7 @@ void cfg_copy_list(list *dest, list *src, unsigned node_size);
 
 extern int (*cf_read_hook)(byte *buf, uint max, int fd);
 
+struct stats_term_config;
 struct symbol {
   node n;                              /* In list of symbols in config */
   struct symbol *next;
@@ -125,6 +126,7 @@ struct symbol {
     struct f_val *val;                 /* For SYM_CONSTANT */
     uint offset;                       /* For SYM_VARIABLE */
     struct channel_config *ch_config;  /* For SYM_COUNTER */
+    struct stats_term_config *term;     /* For SYM_COUNTER_TERM */
   };
 
   char name[0];
@@ -158,6 +160,7 @@ struct bytestring {
 #define SYM_TABLE 5
 #define SYM_ATTRIBUTE 6
 #define SYM_COUNTER 7
+#define SYM_COUNTER_TERM 8
 
 #define SYM_VARIABLE 0x100     /* 0x100-0x1ff are variable types */
 #define SYM_VARIABLE_RANGE SYM_VARIABLE ... (SYM_VARIABLE | 0xff)
index 23b258cd9e1fd66f01152b6374613fd799111661..072ae622bb244a69830010e1b58ea54a920ba915 100644 (file)
@@ -761,6 +761,9 @@ symbol_value: symbol_known
       case SYM_COUNTER:
        $$ = f_new_inst(FI_COUNTER, $1);
        break;
+      case SYM_COUNTER_TERM:
+       $$ = f_new_inst(FI_COUNTER_TERM, $1);
+       break;
       default:
        cf_error("Can't get value of symbol %s", $1->name);
     }
index a1e639f2fb7fa4d9bd8bc9bdd82b29671ecb1010..b0635db435efccab3fc6ba5223bc8a3945a348a6 100644 (file)
   INST(FI_COUNTER, 0, 1) {
     SYMBOL;
     NEVER_CONSTANT;
-    RESULT(T_INT, i, get_stats_counter(sym));
+    RESULT(T_INT, i, stats_get_counter(sym));
+  }
+
+  INST(FI_COUNTER_TERM, 0, 1) {
+    SYMBOL;
+    NEVER_CONSTANT;
+
+    RESULT_TYPE(stats_get_type(sym->term));
+    RESULT_VAL(stats_eval_term(sym->term));
   }
 
   INST(FI_CONSTANT, 0, 1) {
index 51fa0726ad7f623c5468623ab20da0bd6a8765a5..6d477b0052f45b2a59cf1b13aebc940acce88dbb 100644 (file)
@@ -43,7 +43,7 @@
 #include "filter/filter.h"
 #include "filter/f-inst.h"
 #include "filter/data.h"
-#include "proto/stats/stats.h"  /* provides function get_stats_counter() used in f-inst.c */
+#include "proto/stats/stats-pub.h"  /* provides function get_stats_counter() used in f-inst.c */
 
 
 /* Exception bits */
index 458e3ba5247b84e09b4477476dc1a10504a5d8a1..970970d3448b6e401deb22824756d4bdf365cc8d 100644 (file)
@@ -13,11 +13,12 @@ CF_HDR
 
 CF_DEFINES
 
+#define STATS_CFG ((struct stats_config *) this_proto)
 #define STATS_CC ((struct stats_channel_config *) this_channel)
 
 CF_DECLS
 
-CF_KEYWORDS(STATS, TABLE, MAX, GENERATION, SETTLE, TIME)
+CF_KEYWORDS(STATS, TABLE, MAX, MIN, SETTLE, TIME)
 
 %type <cc> stats_channel_start
 
@@ -28,6 +29,7 @@ proto: stats_proto '}' { this_channel = NULL; }  ;
 stats_proto_start: proto_start STATS
 {
   this_proto = proto_config_new(&proto_stats, $1);
+  init_list(&STATS_CFG->terms);
 }
 
 proto_name ;
@@ -39,10 +41,20 @@ stats_channel_opt_list:
 
 stats_opt:
     type symbol '=' term {
-      struct f_val val;
-      if (f_eval(f_linearize($4), &val) > F_RETURN) cf_error("Runtime error");
+      
+      struct stats_term_config *tc = cfg_alloc(sizeof(struct stats_term_config));
+      tc->code = (const struct f_line *) f_linearize($4);
+      tc->type = $1;
+      tc->name = $2->name;
+     
+      struct f_val val; 
+      /* greater then F_RETURN, therefore 2 */
+      if (f_eval(f_linearize($4), &val) > 2) cf_error("Runtime error"); 
       if (val.type != $1) cf_error("The expresion does not match defined type");
-      /* cf_define_symbol($2, SYM_VARIABLE | $1, val )*/
+
+      add_tail(&STATS_CFG->terms, (node *) tc); 
+
+      $2 = cf_define_symbol($2, SYM_COUNTER_TERM, term, tc); 
     }
   | MIN SETTLE TIME expr_us { STATS_CC->min_settle_time = $4; }
   | MAX SETTLE TIME expr_us { STATS_CC->max_settle_time = $4; }
diff --git a/proto/stats/stats-pub.h b/proto/stats/stats-pub.h
new file mode 100644 (file)
index 0000000..7585c2e
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _BIRD_STATS_PUB_H_
+#define _BIRD_STATS_PUB_H_
+
+extern int stats_get_counter(struct symbol *sym);
+extern struct f_val stats_eval_term(struct stats_term_config *tc);
+extern int  stats_get_type(struct stats_term_config *tc);
+#endif
index 406bc226c84f5243a73937b92580643f15bb22b1..253139d561c2d9c72013898d4ab4168382686fc1 100644 (file)
@@ -115,6 +115,16 @@ stats_start(struct proto *P)
 {
   log(L_INFO "stats_start() ");
   stats_configure_channels(P, P->cf);
+
+  struct stats_term_config *tc;
+  WALK_LIST(tc, ((struct stats_config *) P->cf)->terms)
+  {
+    log(L_INFO "term %s", tc->name);
+    f_eval(tc->code, &tc->val);
+    log(L_INFO "content: %s, matches %s", val_dump(&tc->val),
+      tc->type == tc->val.type ? "yes" : "no");
+  }
+
   return PS_UP;
 }
 
@@ -181,6 +191,9 @@ stats_show_proto_info(struct proto *P)
       cli_msg(-1006, "    Settle time:  %4u s", (*(sc->settle_timer->max_settle_time)) TO_S);
     }
   }
+
+  cli_msg(-1006, "  Terms:");
+  cli_msg(-1006, "terms list: %p", ((struct stats_config *) p->c)->terms);
 }
 
 void
@@ -252,6 +265,40 @@ stats_channel_shutdown(struct channel *C)
   c->pool = NULL;
 }
 
+int
+stats_get_counter(struct symbol *sym)
+{
+  if (sym->ch_config->channel)
+    return (int) ((struct stats_channel *) sym->ch_config->channel)->counter;
+  else
+    return 0;
+}
+
+struct f_val
+stats_eval_term(struct stats_term_config *tc)
+{
+  log(L_INFO "stats_eval_term() evaluating value of %s", 
+    tc->name);
+  enum filter_return fret = f_eval(tc->code, &tc->val);
+
+  if (fret > F_RETURN)
+    tc->val.type = T_VOID;
+
+  if (tc->type != tc->val.type)
+    tc->val.type = T_VOID;
+
+  log(L_INFO " stats_eval_term() returning %s", val_dump(&tc->val));
+  return tc->val;
+}
+
+int
+stats_get_type(struct stats_term_config *tc)
+{
+  log(L_INFO "stats_get_type()");
+  return tc->type;
+}
+
+
 struct channel_class channel_stats = {
   .channel_size =      sizeof(struct stats_channel),
   .config_size =       sizeof(struct stats_channel_config),
index ec5fbd127e32762be247d3197f0afc03b4d079e4..f78df73cad77d035d38a300b0b6e7c6342e05059 100644 (file)
 #ifndef _BIRD_STATS_H_
 #define _BIRD_STATS_H_
 #include "lib/timer.h"
+#include "filter/data.h"
 
 struct stats_channel;
 
+struct stats_term_config {
+  node n;
+  const struct f_line *code;
+  struct f_val val;
+  int type;                     /* type declared in configuration */
+  const char *name;
+};
+
 struct stats_config {
   struct proto_config c;
+  list terms;                    /* list of counter terms */
 };
 
 struct stats_proto {
@@ -37,13 +47,18 @@ struct stats_channel_config {
   btime max_settle_time;
 };
 
+int stats_get_counter(struct symbol *sym);
+struct f_val stats_eval_term(struct stats_term_config *tc);
+int stats_get_type(struct stats_term_config *tc);
+
+#if 0
 /*
  * get_stats_counter() - extract last notified counter
  *   for specific stats channel if it runs
  *
  */
-static inline int
-get_stats_counter(struct symbol *sym)
+inline int
+stats_get_counter(struct symbol *sym)
 {
   if (sym->ch_config->channel)
     return (int) ((struct stats_channel *) sym->ch_config->channel)->counter;
@@ -51,4 +66,30 @@ get_stats_counter(struct symbol *sym)
     return 0;
 }
 
+/*
+ * stats_eval_term() - evaluate stats term
+ *
+ */
+inline struct f_val
+stats_eval_term(struct stats_term_config *tc)
+{
+  enum filter_return fret = f_eval(tc->code, &tc->val);
+
+  if (fret > F_RETURN)
+    tc->val.type = T_VOID;
+
+  if (tc->type != tc->val.type)
+    tc->val.type = T_VOID;
+
+  return tc->val;
+}
+
+int
+stats_get_type(struct stats_term_config *tc)
+{
+  return tc->type;
+}
+
+#endif // if 0
+
 #endif