]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Nest: Implement 'show route in <addr>' command
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Thu, 2 Dec 2021 01:22:30 +0000 (02:22 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Sun, 6 Feb 2022 22:27:13 +0000 (23:27 +0100)
Implement 'show route in <addr>' command, which shows all routes in
networks that are subnets of given network. Currently limited to IP
network types.

nest/config.Y
nest/route.h
nest/rt-show.c

index 7ead858939460cdd2d36606bd0e220b59738632e..310fce253bcde48cf655ea4adcfdaca5d01c22ed 100644 (file)
@@ -117,7 +117,7 @@ CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS)
 CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED, RPKI)
 CF_KEYWORDS(PASSWORD, KEY, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, CHANNELS, INTERFACES)
 CF_KEYWORDS(ALGORITHM, KEYED, HMAC, MD5, SHA1, SHA256, SHA384, SHA512, BLAKE2S128, BLAKE2S256, BLAKE2B256, BLAKE2B512)
-CF_KEYWORDS(PRIMARY, STATS, COUNT, BY, FOR, COMMANDS, PREEXPORT, NOEXPORT, EXPORTED, GENERATE)
+CF_KEYWORDS(PRIMARY, STATS, COUNT, BY, FOR, IN, COMMANDS, PREEXPORT, NOEXPORT, EXPORTED, GENERATE)
 CF_KEYWORDS(BGP, PASSWORDS, DESCRIPTION, SORTED)
 CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP)
 CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, ROUTE, PROTOCOL, BASE, LOG, S, MS, US)
@@ -621,14 +621,22 @@ r_args:
      $$ = $1;
      if ($$->addr) cf_error("Only one prefix expected");
      $$->addr = $2;
+     $$->addr_mode = RSD_ADDR_EQUAL;
    }
  | r_args FOR r_args_for {
      $$ = $1;
      if ($$->addr) cf_error("Only one prefix expected");
-     $$->show_for = 1;
      $$->addr = $3;
+     $$->addr_mode = RSD_ADDR_FOR;
    }
- | r_args TABLE CF_SYM_KNOWN {
+ | r_args IN net_any {
+     $$ = $1;
+     if ($$->addr) cf_error("Only one prefix expected");
+     if (!net_type_match($3, NB_IP)) cf_error("Only IP networks accepted for 'in' argument");
+     $$->addr = $3;
+     $$->addr_mode = RSD_ADDR_IN;
+   }
+| r_args TABLE CF_SYM_KNOWN {
      cf_assert_symbol($3, SYM_TABLE);
      $$ = $1;
      rt_show_add_table($$, $3->table->table);
index fa87e22cc99ed159ec84ebf68bed48c4e10bbe20..ace4c7f71a5068bbd58f9a992abaf9f2fba078d0 100644 (file)
@@ -384,7 +384,7 @@ struct rt_show_data {
   struct channel *export_channel;
   struct config *running_on_config;
   struct krt_proto *kernel;
-  int export_mode, primary_only, filtered, stats, show_for;
+  int export_mode, addr_mode, primary_only, filtered, stats;
 
   int table_open;                      /* Iteration (fit) is open */
   int net_counter, rt_counter, show_counter, table_counter;
@@ -403,6 +403,11 @@ struct rt_show_data_rtable * rt_show_add_table(struct rt_show_data *d, rtable *t
 #define RSD_TDB_SET      0x1           /* internal: show empty tables */
 #define RSD_TDB_NMN      0x2           /* internal: need matching net */
 
+/* Value of addr_mode */
+#define RSD_ADDR_EQUAL 1               /* Exact query - show route <addr> */
+#define RSD_ADDR_FOR   2               /* Longest prefix match - show route for <addr> */
+#define RSD_ADDR_IN    3               /* Interval query - show route in <addr> */
+
 /* Value of export_mode in struct rt_show_data */
 #define RSEM_NONE      0               /* Export mode not used */
 #define RSEM_PREEXPORT 1               /* Routes ready for export, before filtering */
index 7691878dd6dcfb6887ae29abe78dfc98bd99ba9c..b8c818f88bf8ba11d850b99cc74cc68a9ac998df 100644 (file)
@@ -255,12 +255,17 @@ rt_show_cont(struct cli *c)
 
   FIB_ITERATE_START(fib, it, net, n)
   {
+    if ((d->addr_mode == RSD_ADDR_IN) && (!net_in_netX(n->n.addr, d->addr)))
+      goto next;
+
     if (!max--)
     {
       FIB_ITERATE_PUT(it);
       return;
     }
     rt_show_net(c, n, d);
+
+  next:;
   }
   FIB_ITERATE_END;
 
@@ -402,7 +407,7 @@ rt_show(struct rt_show_data *d)
 
   rt_show_prepare_tables(d);
 
-  if (!d->addr)
+  if (!d->addr || (d->addr_mode == RSD_ADDR_IN))
   {
     WALK_LIST(tab, d->tables)
       rt_lock_table(tab->table);
@@ -420,7 +425,7 @@ rt_show(struct rt_show_data *d)
       d->tab = tab;
       d->kernel = rt_show_get_kernel(d);
 
-      if (d->show_for)
+      if (d->addr_mode == RSD_ADDR_FOR)
        n = net_route(tab->table, d->addr);
       else
        n = net_find(tab->table, d->addr);