]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Remove old pipe protocol code. Add init function.
authorVojtech Vilimek <vojtech.vilimek@nic.cz>
Thu, 14 Jul 2022 12:51:03 +0000 (14:51 +0200)
committerVojtech Vilimek <vojtech.vilimek@nic.cz>
Thu, 14 Jul 2022 12:51:03 +0000 (14:51 +0200)
proto/stats/config.Y
proto/stats/stats.c
proto/stats/stats.h

index cf9a9066cd09be118dbd94e0516c6642d2fe0a32..e66f18d13f807a2f48dfea91a2641d1d71128ae1 100644 (file)
@@ -1,7 +1,8 @@
 /*
- *     BIRD -- Table-to-Table Protocol Configuration
+ *     BIRD -- Statistics Protocol Configuration
  *
- *     (c) 1999 Martin Mares <mj@ucw.cz>
+ *      (c) 2022 Vojtech Vilimek <vojtech.vilimek@nic.cz>
+ *      (c) 2022 CZ.NIC z.s.p.o. 
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
@@ -19,8 +20,9 @@ CF_DEFINES
 CF_DECLS
 
 /* TODO here add more keywords */
-/* old: CF_KEYWORDS(PIPE, PEER, TABLE, MAX, GENERATION) */
-CF_KEYWORDS(STATS, PEER, TABLE, MAX, GENERATION)
+CF_KEYWORDS(STATS, TABLE, MAX, GENERATION)
+
+%type <cc> stats_channel_start
 
 CF_GRAMMAR
 
@@ -31,31 +33,21 @@ stats_proto_start: proto_start STATS
   this_proto = proto_config_new(&proto_stats, $1);
   STATS_CFG->max_generation = 16;
 }
-proto_name
+
+proto_name ;
+
+stats_proto_channel: stats_channel_start channel_opt_list channel_end ;
+
+stats_channel_start: net_type symbol
 {
-  this_channel = proto_cf_main_channel(this_proto);
-  if (!this_channel) {
-    this_channel = channel_config_new(NULL, NULL, 0, this_proto);
-    this_channel->in_filter = FILTER_ACCEPT;
-    this_channel->out_filter = FILTER_ACCEPT;
-  }
-};
+  $$ = this_channel = channel_config_get(NULL, $2->name, $1, this_proto);
+}
 
 stats_proto:
    stats_proto_start '{'
  | stats_proto proto_item ';'
- | stats_proto channel_item_ ';'
- | stats_proto IMPORT IN net_any imexport ';' {
-    if (this_channel->net_type && ($4->type != this_channel->net_type))
-      cf_error("Incompatible export prefilter type");
-    STATS_CFG->in_subprefix = $4;
-    this_channel->in_filter = $5;
-  }
- | stats_proto PEER TABLE rtable ';' { STATS_CFG->peer = $4; }
- | stats_proto MAX GENERATION expr ';' {
-    if (($4 < 1) || ($4 > 254)) cf_error("Max generation must be in range 1..254, got %u", $4);
-    STATS_CFG->max_generation = $4;
-  }
+ | stats_proto stats_proto_channel ';'
+ | stats_proto  ';'
  ;
 
 CF_CODE
index c4af70f1b2cafa44545c13f666c000b93769457c..8f240710fea011c41d47b5dbf51948b52d620d14 100644 (file)
@@ -1,33 +1,15 @@
 /*
  *     BIRD -- Table-to-Table Routing Protocol a.k.a Pipe
  *
- *     (c) 1999--2000 Martin Mares <mj@ucw.cz>
+ *      (c) 2022       Vojtech Vilimek <vojtech.vilimek@nic.cz>
+ *      (c) 2022       CZ.NIC z.s.p.o.
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
 
 /**
- * DOC: Pipe
+ * DOC: Stats
  *
- * The Pipe protocol is very simple. It just connects to two routing tables
- * using proto_add_announce_hook() and whenever it receives a rt_notify()
- * about a change in one of the tables, it converts it to a rte_update()
- * in the other one.
- *
- * To avoid pipe loops, Pipe keeps a `being updated' flag in each routing
- * table.
- *
- * A pipe has two announce hooks, the first connected to the main
- * table, the second connected to the peer table. When a new route is
- * announced on the main table, it gets checked by an export filter in
- * ahook 1, and, after that, it is announced to the peer table via
- * rte_update(), an import filter in ahook 2 is called. When a new
- * route is announced in the peer table, an export filter in ahook2
- * and an import filter in ahook 1 are used. Oviously, there is no
- * need in filtering the same route twice, so both import filters are
- * set to accept, while user configured 'import' and 'export' filters
- * are used as export filters in ahooks 2 and 1. Route limits are
- * handled similarly, but on the import side of ahooks.
  */
 
 #undef LOCAL_DEBUG
@@ -51,25 +33,6 @@ 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 channel *dst = (src_ch == p->pri) ? p->sec : p->pri;
-
-  if (!new && !old)
-    return;
-
-  if (new)
-    {
-      rte e0 = {
-       .attrs = new->attrs,
-       .src = new->src,
-       .generation = new->generation + 1,
-      };
-
-      ea_unset_attr(&e0.attrs, 0, &ea_gen_hostentry);
-
-      rte_update(dst, n, &e0, new->src);
-    }
-  else
-    rte_update(dst, n, NULL, old->src);
 }
 
 static int
@@ -77,21 +40,6 @@ stats_preexport(struct channel *c, rte *e)
 {
   struct stats_proto *p = (void *) c->proto;
 
-  /* Avoid direct loopbacks */
-  if (e->sender == c->in_req.hook)
-    return -1;
-
-  /* Indirection check */
-  uint max_generation = ((struct stats_config *) p->p.cf)->max_generation;
-  if (e->generation >= max_generation)
-  {
-    log_rl(&p->rl_gen, L_ERR "Route overpiped (%u hops of %u configured in %s) in table %s: %N %s/%u:%u",
-       e->generation, max_generation, c->proto->name,
-       c->table->name, e->net, e->src->proto->name, e->src->private_id, e->src->global_id);
-
-    return -1;
-  }
-
   return 0;
 }
 
@@ -101,76 +49,9 @@ stats_reload_routes(struct channel *C)
   struct stats_proto *p = (void *) C->proto;
 
   /* Route reload on one channel is just refeed on the other */
-  channel_request_feeding((C == p->pri) ? p->sec : p->pri);
-}
-
-
-static void
-stats_postconfig(struct proto_config *CF)
-{
-  struct stats_config *cf = (void *) CF;
-  struct channel_config *cc = proto_cf_main_channel(CF);
-
-  if (!cc->table)
-    cf_error("Primary routing table not specified");
-
-  if (!cf->peer)
-    cf_error("Secondary routing table not specified");
-
-  if (cc->table == cf->peer)
-    cf_error("Primary table and peer table must be different");
-
-  if (cc->table->addr_type != cf->peer->addr_type)
-    cf_error("Primary table and peer table must have the same type");
-
-  if (cc->out_subprefix && (cc->table->addr_type != cc->out_subprefix->type))
-    cf_error("Export subprefix must match table type");
-
-  if (cf->in_subprefix && (cc->table->addr_type != cf->in_subprefix->type))
-    cf_error("Import subprefix must match table type");
-
-  if (cc->rx_limit.action)
-    cf_error("Pipe protocol does not support receive limits");
-
-  if (cc->in_keep)
-    cf_error("Pipe protocol prohibits keeping filtered routes");
-
-  cc->debug = cf->c.debug;
+  channel_request_feeding(p->c);
 }
 
-static int
-stats_configure_channels(struct stats_proto *s, struct stats_config *cf)
-{
-  struct channel_config *cc = proto_cf_main_channel(&cf->c);
-
-  struct channel_config pri_cf = {
-    .name = "pri",
-    .channel = cc->channel,
-    .table = cc->table,
-    .out_filter = cc->out_filter,
-    .out_subprefix = cc->out_subprefix,
-    .in_limit = cc->in_limit,
-    .ra_mode = RA_ANY,
-    .debug = cc->debug,
-    .rpki_reload = cc->rpki_reload,
-  };
-
-  struct channel_config sec_cf = {
-    .name = "sec",
-    .channel = cc->channel,
-    .table = cf->peer,
-    .out_filter = cc->in_filter,
-    .out_subprefix = cf->in_subprefix,
-    .in_limit = cc->out_limit,
-    .ra_mode = RA_ANY,
-    .debug = cc->debug,
-    .rpki_reload = cc->rpki_reload,
-  };
-
-  return
-    proto_configure_channel(&s->p, &s->pri, &pri_cf) &&
-    proto_configure_channel(&s->p, &s->sec, &sec_cf);
-}
 
 static struct proto *
 stats_init(struct proto_config *CF)
@@ -185,7 +66,12 @@ stats_init(struct proto_config *CF)
 
   p->rl_gen = (struct tbf) TBF_DEFAULT_LOG_LIMITS;
 
-  stats_configure_channels(p, cf);
+  struct channel_config *cc;
+  WALK_LIST(cc, CF->channels) 
+  {
+    struct channel *c = NULL;
+    proto_configure_channel(P, &c, cc);
+  }
 
   return P;
 }
@@ -196,7 +82,8 @@ stats_reconfigure(struct proto *P, struct proto_config *CF)
   struct stats_proto *p = (void *) P;
   struct stats_config *cf = (void *) CF;
 
-  return stats_configure_channels(p, cf);
+  //return stats_configure_channels(p, cf);
+  return 1;
 }
 
 static void
@@ -209,62 +96,12 @@ static void
 stats_get_status(struct proto *P, byte *buf)
 {
   struct stats_proto *p = (void *) P;
-
-  bsprintf(buf, "%s <=> %s", p->pri->table->name, p->sec->table->name);
 }
 
 static void
 stats_show_stats(struct stats_proto *p)
 {
-  struct channel_import_stats *s1i = &p->pri->import_stats;
-  struct channel_export_stats *s1e = &p->pri->export_stats;
-  struct channel_import_stats *s2i = &p->sec->import_stats;
-  struct channel_export_stats *s2e = &p->sec->export_stats;
-
-  struct rt_import_stats *rs1i = p->pri->in_req.hook ? &p->pri->in_req.hook->stats : NULL;
-  struct rt_export_stats *rs1e = p->pri->out_req.hook ? &p->pri->out_req.hook->stats : NULL;
-  struct rt_import_stats *rs2i = p->sec->in_req.hook ? &p->sec->in_req.hook->stats : NULL;
-  struct rt_export_stats *rs2e = p->sec->out_req.hook ? &p->sec->out_req.hook->stats : NULL;
-
-  u32 pri_routes = p->pri->in_limit.count;
-  u32 sec_routes = p->sec->in_limit.count;
 
-  /*
-   * Pipe stats (as anything related to pipes) are a bit tricky. There
-   * are two sets of stats - s1 for ahook to the primary routing and
-   * s2 for the ahook to the secondary routing table. The user point
-   * of view is that routes going from the primary routing table to
-   * the secondary routing table are 'exported', while routes going in
-   * the other direction are 'imported'.
-   *
-   * 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, ...).
-   *
-   * Rule of thumb is that stats s1 have the correct 'polarity'
-   * (imp/exp), while stats s2 have switched 'polarity'.
-   */
-
-  cli_msg(-1006, "  Routes:         %u imported, %u exported",
-         pri_routes, sec_routes);
-  cli_msg(-1006, "  Route change stats:     received   rejected   filtered    ignored   accepted");
-  cli_msg(-1006, "    Import updates:     %10u %10u %10u %10u %10u",
-         rs2e->updates_received, s2e->updates_rejected + s1i->updates_invalid,
-         s2e->updates_filtered, rs1i->updates_ignored, rs1i->updates_accepted);
-  cli_msg(-1006, "    Import withdraws:   %10u %10u        --- %10u %10u",
-         rs2e->withdraws_received, s1i->withdraws_invalid,
-         rs1i->withdraws_ignored, rs1i->withdraws_accepted);
-  cli_msg(-1006, "    Export updates:     %10u %10u %10u %10u %10u",
-         rs1e->updates_received, s1e->updates_rejected + s2i->updates_invalid,
-         s1e->updates_filtered, rs2i->updates_ignored, rs2i->updates_accepted);
-  cli_msg(-1006, "    Export withdraws:   %10u %10u        --- %10u %10u",
-         rs1e->withdraws_received, s2i->withdraws_invalid,
-         rs2i->withdraws_ignored, rs2i->withdraws_accepted);
 }
 
 static void
@@ -272,23 +109,6 @@ stats_show_proto_info(struct proto *P)
 {
   struct stats_proto *p = (void *) P;
 
-  cli_msg(-1006, "  Channel %s", "main");
-  cli_msg(-1006, "    Table:          %s", p->pri->table->name);
-  cli_msg(-1006, "    Peer table:     %s", p->sec->table->name);
-  cli_msg(-1006, "    Import state:   %s", rt_export_state_name(rt_export_get_state(p->sec->out_req.hook)));
-  cli_msg(-1006, "    Export state:   %s", rt_export_state_name(rt_export_get_state(p->pri->out_req.hook)));
-  cli_msg(-1006, "    Import filter:  %s", filter_name(p->sec->out_filter));
-  cli_msg(-1006, "    Export filter:  %s", filter_name(p->pri->out_filter));
-
-
-
-  channel_show_limit(&p->pri->in_limit, "Import limit:",
-      (p->pri->limit_active & (1 << PLD_IN)), p->pri->limit_actions[PLD_IN]);
-  channel_show_limit(&p->sec->in_limit, "Export limit:",
-      (p->sec->limit_active & (1 << PLD_IN)), p->sec->limit_actions[PLD_IN]);
-
-  if (P->proto_state != PS_DOWN)
-    stats_show_stats(p);
 }
 
 void
@@ -296,16 +116,16 @@ stats_update_debug(struct proto *P)
 {
   struct stats_proto *p = (void *) P;
 
-  p->pri->debug = p->sec->debug = p->p.debug;
+  p->c->debug = p->p.debug;
 }
 
 
 struct protocol proto_stats = {
   .name =              "Stats",
   .template =          "stat%d",
+  .channel_mask =      NB_ANY,
   .proto_size =                sizeof(struct stats_proto),
   .config_size =       sizeof(struct stats_config),
-  .postconfig =                stats_postconfig,
   .init =              stats_init,
   .reconfigure =       stats_reconfigure,
   .copy_config =       stats_copy_config,
index 2634e51a28e562308b7f57d4c2fa31dbf92b94a7..6d448d4b1c941a14ce7aa4d03c0019ebfaa1b490 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *     BIRD -- Table-to-Table Routing Protocol a.k.a Pipe
  *
- *     (c) 1999 Martin Mares <mj@ucw.cz>
+ *      (c) 2022 Vojtech Vilimek <vojtech.vilimek@nic.cz>
+ *      (c) 2022 CZ.NIC z.s.p.o.
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
 
 struct stats_config {
   struct proto_config c;
-  struct rtable_config *peer;          /* Table we're connected to */
   const net_addr *in_subprefix;
   u8 max_generation;
 };
 
 struct stats_proto {
   struct proto p;
-  struct channel *pri;
-  struct channel *sec;
+  struct channel *c;
   struct tbf rl_gen;
 };