]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
MPLS: Add command 'show mpls ranges'
authorOndrej Zajicek <santiago@crfreenet.org>
Mon, 18 Sep 2023 15:32:24 +0000 (17:32 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Wed, 4 Oct 2023 11:12:05 +0000 (13:12 +0200)
Add command to show MPLS label ranges and their stats.

conf/confbase.Y
doc/reply_codes
nest/mpls.Y
nest/mpls.c
nest/mpls.h

index 63308290f41d6b91790c5f6bbd8d6fa48b77e3fe..2c37bd4d0c316a79eb7fa469069b0e6b353c32a1 100644 (file)
@@ -88,6 +88,7 @@ CF_DECLS
   struct sym_show_data *sd;
   struct lsadb_show_data *ld;
   struct mrt_dump_data *md;
+  struct mpls_show_ranges_cmd *msrc;
   struct iface *iface;
   void *g;
   btime time;
index 02f4e656084891aa21e41cdaa8c02746f4d2a156..71cdf341da72a9a211d2561d223ef7b261fea862 100644 (file)
@@ -61,6 +61,7 @@ Reply codes of BIRD command-line interface
 1023   Show Babel interfaces
 1024   Show Babel neighbors
 1025   Show Babel entries
+1026   Show MPLS ranges
 
 8000   Reply too long
 8001   Route not found
index 5c46392c078e61639d82e2ff312e63099424ed5d..0e755fec84aa58a02fc5b1545ec84202f2d6e982 100644 (file)
@@ -24,6 +24,7 @@ CF_KEYWORDS(MPLS, DOMAIN, LABEL, RANGE, STATIC, DYNAMIC, START, LENGTH, POLICY,
 
 %type <i> mpls_label_policy
 %type <cc> mpls_channel_start mpls_channel
+%type <msrc> show_mpls_ranges_args
 
 CF_GRAMMAR
 
@@ -137,6 +138,59 @@ mpls_channel_opt_list:
 mpls_channel_end: { mpls_channel_postconfig(this_channel); } channel_end;
 
 
+show_mpls_ranges_args:
+   /* empty */
+   {
+     if (EMPTY_LIST(config->mpls_domains))
+       cf_error("No MPLS domain defined");
+
+     $$ = cfg_allocz(sizeof(struct mpls_show_ranges_cmd));
+   }
+ | show_mpls_ranges_args symbol_known
+   {
+     if ($2->class == SYM_MPLS_DOMAIN)
+     {
+       if ($$->domain)
+       cf_error("Only one MPLS domain expected");
+
+       $$->domain = $2->mpls_domain;
+     }
+     else if ($2->class == SYM_MPLS_RANGE)
+     {
+       if ($$->range)
+       cf_error("Only one MPLS label range expected");
+
+       if ($$->domain != $2->mpls_range->domain)
+       cf_error("MPLS label range from different MPLS domain");
+
+       $$->domain = $2->mpls_range->domain;
+       $$->range = $2->mpls_range;
+     }
+     else
+       cf_error("MPLS domain or label range expected");
+   }
+ | show_mpls_ranges_args STATIC
+   {
+     if ($$->range)
+       cf_error("Only one MPLS label range expected");
+
+     $$->domain = $$->domain ?: cf_default_mpls_domain(config);
+     $$->range = $$->domain->static_range;
+   }
+ | show_mpls_ranges_args DYNAMIC
+   {
+     if ($$->range)
+       cf_error("Only one MPLS label range expected");
+
+     $$->domain = $$->domain ?: cf_default_mpls_domain(config);
+     $$->range = $$->domain->dynamic_range;
+   }
+ ;
+
+CF_CLI(SHOW MPLS RANGES, show_mpls_ranges_args, [<MPLS domain> | <MPLS range>], [[Show MPLS ranges]])
+{ mpls_show_ranges($4); } ;
+
+
 CF_CODE
 
 CF_END
index df03a86b18549be3776f3697a8f3fcf6a6e319ce..788de7c132a991755ea75e7e17c2f438a23cf5b0 100644 (file)
@@ -76,7 +76,6 @@
  * and withdrawal of MPLS routes.
  *
  * TODO:
- *  - show mpls labels CLI command
  *  - label range non-intersection check
  *  - better range reconfigurations (allow reduce ranges over unused labels)
  *  - protocols should do route refresh instead of resetart when reconfiguration
@@ -89,6 +88,7 @@
 #include "nest/bird.h"
 #include "nest/route.h"
 #include "nest/mpls.h"
+#include "nest/cli.h"
 
 static struct mpls_range *mpls_new_range(struct mpls_domain *m, struct mpls_range_config *cf);
 static struct mpls_range *mpls_find_range_(list *l, const char *name);
@@ -1038,3 +1038,50 @@ mpls_rte_remove(net *n UNUSED, rte *r)
 
   mpls_unlock_fec(m, fec);
 }
+
+static void
+mpls_show_ranges_rng(struct mpls_show_ranges_cmd *cmd, struct mpls_range *r)
+{
+  uint last = lmap_last_one_in_range(&cmd->dom->labels, r->lo, r->hi);
+  if (last == r->hi) last = 0;
+
+  cli_msg(-1026, "%-11s %7u %7u %7u %7u %7u",
+         r->name, r->lo, r->hi - r->lo, r->hi, r->label_count, last);
+}
+
+void
+mpls_show_ranges_dom(struct mpls_show_ranges_cmd *cmd, struct mpls_domain *m)
+{
+  if (cmd->dom)
+    cli_msg(-1026, "");
+
+  cmd->dom = m;
+  cli_msg(-1026, "MPLS domain %s:", m->name);
+  cli_msg(-1026, "%-11s %7s %7s %7s %7s %7s",
+         "Range", "Start", "Length", "End", "Labels", "Last");
+
+  if (cmd->range)
+    mpls_show_ranges_rng(cmd, cmd->range->range);
+  else
+  {
+    struct mpls_range *r;
+    WALK_LIST(r, m->ranges)
+      if (!r->removed)
+       mpls_show_ranges_rng(cmd, r);
+  }
+}
+
+void
+mpls_show_ranges(struct mpls_show_ranges_cmd *cmd)
+{
+  if (cmd->domain)
+    mpls_show_ranges_dom(cmd, cmd->domain->domain);
+  else
+  {
+    struct mpls_domain *m;
+    WALK_LIST(m, mpls_domains)
+      mpls_show_ranges_dom(cmd, m);
+  }
+
+  cli_msg(0, "");
+}
index 4b071ad8bff14ad885a5c7af394202a24673f1a9..bac5c69d4a68311cbd049a11758904a96c988a57 100644 (file)
@@ -171,4 +171,15 @@ void mpls_handle_rte_cleanup(struct mpls_fec_map *m, struct mpls_fec **locked_fe
 void mpls_rte_insert(net *n UNUSED, rte *r);
 void mpls_rte_remove(net *n UNUSED, rte *r);
 
+
+struct mpls_show_ranges_cmd {
+  struct mpls_domain_config *domain;
+  struct mpls_range_config *range;
+
+  /* Runtime */
+  struct mpls_domain *dom;
+};
+
+void mpls_show_ranges(struct mpls_show_ranges_cmd *cmd);
+
 #endif