]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
CLI: v2 compatibility mode for attribute name display
authorMaria Matejka <mq@ucw.cz>
Wed, 18 Dec 2024 11:24:49 +0000 (12:24 +0100)
committerMaria Matejka <mq@ucw.cz>
Mon, 13 Jan 2025 20:51:14 +0000 (21:51 +0100)
Also fixed display of bgp_otc (was just "otc" before).

14 files changed:
doc/bird.sgml
lib/route.h
nest/cli.c
nest/cli.h
nest/rt-attr.c
nest/rt-show.c
proto/babel/babel.c
proto/bgp/attrs.c
proto/ospf/ospf.c
proto/radv/radv.c
proto/rip/rip.c
sysdep/linux/netlink.c
sysdep/unix/config.Y
sysdep/unix/krt.c

index a3563c666abea415f84a2177755644a1a0817e66..b92aab25b8ecb6adaa9e8893d23a891b89597604 100644 (file)
@@ -1293,16 +1293,25 @@ connects to it. If changed on the command line by the <tt/-s/ option,
 BIRD or the CLI tool connects there instead.
 
 <p>It's also possible to configure additional remote control sockets in the
-configuration file by <cf/cli "name";/ and you can open how many
+configuration file by <cf/cli "name" { <m/options/ };/ and you can open how many
 sockets you wish. There are no checks whether the user configured the same
 socket multiple times and BIRD may behave weirdly if this happens. On shutdown,
 the additional sockets get removed immediately and only the main socket stays
-until the very end.
+until the very end. If there are no options, the braces may be omitted.
 
-<p>The remote control socket can be also set as restricted by
-<cf/cli "name" { restrict; };/ instead of sending the <cf/restrict/ command
-after connecting. The user may still overload the daemon by requesting insanely
-complex filters so you shouldn't expose this socket to public anyway.
+<p>Options:
+
+<descrip>
+       <tag><label id="cli-conf-restrict">restrict</tag>
+       Set the socket to be restricted as if the user always sent the
+       <cf/restrict/ command after connecting. The user may still overload
+       the daemon by requesting insanely complex filters so you shouldn't
+       expose this socket to public even if restricted.
+
+       <tag><label id="cli-conf-v2-attributes">v2 attributes</tag>
+       Display the names and composition of route attributes the same way as BIRD 2 does.
+       This is a compatibility option for easier transition from BIRD 2 to BIRD 3.
+</descrip>
 
 <sect>Usage
 <label id="remote-control-usage">
index 6ad4a7c7d94b9d6ef6b579f866fa6c3c20cb04bd..21b46820867fbec7e8d39b8f13d093c58250dec7 100644 (file)
@@ -267,6 +267,7 @@ struct ea_storage {
 struct ea_class {
 #define EA_CLASS_INSIDE \
   const char *name;                    /* Name (both print and filter) */ \
+  const char *legacy_name;             /* Name for printing in v2 sockets */ \
   struct symbol *sym;                  /* Symbol to export to configs */ \
   uint id;                             /* Autoassigned attribute ID */ \
   uint uc;                             /* Reference count */ \
index b33ffd43789dbdf948de07d261b00db0042e6560..865e7f15fb5e659edfd688b5da18a0c261a2aaff 100644 (file)
@@ -320,6 +320,8 @@ cli_new(struct birdsock *sock, struct cli_config *cf)
   if (cf->restricted)
     c->restricted = 1;
 
+  c->v2attributes = cf->v2attributes;
+
   ev_schedule(c->event);
   return c;
 }
index 671be04d8cbc91bcf9ef3f769dc36b8a91ea98ff..5436219ee614c385e702cc996e53b0a8550ddd92 100644 (file)
@@ -43,6 +43,7 @@ typedef struct cli {
   struct config *main_config;          /* Main config currently in use */
   int last_reply;
   int restricted;                      /* CLI is restricted to read-only commands */
+  bool v2attributes;                   /* Route attributes are mimicking BIRD 2 */
   struct timeformat *tf;               /* Time format override */
   struct linpool *parser_pool;         /* Pool used during parsing */
   uint log_mask;                       /* Mask of allowed message levels */
@@ -63,6 +64,7 @@ struct cli_config {
   struct config *config;
   uint uid, gid, mode;
   _Bool restricted;
+  _Bool v2attributes;
 };
 #include "lib/tlists.h"
 
index f4e09083e4e7769519ec6897b40ac8044e4b88b7..3aaca0a463ecc2ee8ceeb2979da33e35e4be0b04 100644 (file)
@@ -196,6 +196,7 @@ ea_gen_aspa_providers_format(const eattr *a, byte *buf, uint size)
 
 struct ea_class ea_gen_aspa_providers = {
   .name = "aspa_providers",
+  .legacy_name = "aspa_providers",
   .type = T_CLIST,
   .format = ea_gen_aspa_providers_format,
 };
@@ -1311,7 +1312,12 @@ ea_show(struct cli *c, const eattr *e)
 
   if (e->undef || cls->hidden)
     return;
-  else if (cls->format)
+
+  const char *name = (c->v2attributes && !cls->conf) ? cls->legacy_name : cls->name;
+  if (!name)
+    return;
+
+  if (cls->format)
     cls->format(e, buf, end - buf);
   else
     switch (e->type)
@@ -1356,7 +1362,7 @@ ea_show(struct cli *c, const eattr *e)
          bsprintf(pos, "<type %02x>", e->type);
       }
 
-  cli_printf(c, -1012, "\t%s: %s", cls->name, buf);
+  cli_printf(c, -1012, "\t%s: %s", name, buf);
 }
 
 static void
index aa9209ca5f843a1033cad28da72aeda103688be5..3e1e9b54f3948a8db63c51fd5078038720f9c811 100644 (file)
@@ -21,6 +21,8 @@
 static void rt_show_cont(struct cli *c);
 static void rt_show_done(struct rt_show_data *d);
 
+extern const char * const rta_src_names[RTS_MAX];
+
 static void
 rt_show_table(struct rt_show_data *d)
 {
@@ -81,9 +83,19 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary
 
   if (d->verbose)
   {
+    if (c->v2attributes)
+    {
+      ea_show_nexthop_list(c, nhad);
+
+      uint src = ea_get_int(a, &ea_gen_source, 0);
+      cli_printf(c, -1008, "\tType: %s univ", rta_src_names[src]);
+    }
+
     ea_show_list(c, a);
-    cli_printf(c, -1008, "\tInternal route handling values: %luL %uG %uS id %u",
-       e->src->private_id, e->src->global_id, e->stale_cycle, e->id);
+
+    if (!c->v2attributes)
+      cli_printf(c, -1008, "\tInternal route handling values: %luL %uG %uS id %u",
+         e->src->private_id, e->src->global_id, e->stale_cycle, e->id);
   }
   else if (dest == RTD_UNICAST)
     ea_show_nexthop_list(c, nhad);
index 65f19c4a96c573f208c61acd7381a359ba9ef5e1..2c92d1978159c9660bb2ff916d73ab430a8c3258 100644 (file)
@@ -2206,11 +2206,13 @@ babel_router_id_format(const eattr *a, byte *buf, uint len)
 
 static struct ea_class ea_babel_metric = {
   .name = "babel_metric",
+  .legacy_name = "Babel.metric",
   .type = T_INT,
 };
 
 static struct ea_class ea_babel_router_id = {
   .name = "babel_router_id",
+  .legacy_name = "Babel.router_id",
   .type = T_OPAQUE,
   .readonly = 1,
   .format = babel_router_id_format,
@@ -2218,6 +2220,7 @@ static struct ea_class ea_babel_router_id = {
 
 static struct ea_class ea_babel_seqno = {
   .name = "babel_seqno",
+  .legacy_name = "Babel.seqno",
   .type = T_INT,
   .readonly = 1,
   .hidden = 1,
index db654234343e3af0eb63c11ee0926c0672e6b262..b1be9979d2c5d438a6d4bba80a110d4cdc9c40ec 100644 (file)
@@ -1058,6 +1058,7 @@ bgp_format_unknown(const eattr *a, byte *buf, uint size)
 static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   [BA_ORIGIN] = {
     .name = "bgp_origin",
+    .legacy_name = "BGP.origin",
     .type = T_ENUM_BGP_ORIGIN,
     .flags = BAF_TRANSITIVE,
     .export = bgp_export_origin,
@@ -1067,6 +1068,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_AS_PATH] = {
     .name = "bgp_path",
+    .legacy_name = "BGP.as_path",
     .type = T_PATH,
     .flags = BAF_TRANSITIVE,
     .encode = bgp_encode_as_path,
@@ -1074,6 +1076,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_NEXT_HOP] = {
     .name = "bgp_next_hop",
+    .legacy_name = "BGP.next_hop",
     .type = T_IP,
     .flags = BAF_TRANSITIVE,
     .encode = bgp_encode_next_hop,
@@ -1082,6 +1085,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_MULTI_EXIT_DISC] = {
     .name = "bgp_med",
+    .legacy_name = "BGP.med",
     .type = T_INT,
     .flags = BAF_OPTIONAL,
     .encode = bgp_encode_u32,
@@ -1089,6 +1093,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_LOCAL_PREF] = {
     .name = "bgp_local_pref",
+    .legacy_name = "BGP.local_pref",
     .type = T_INT,
     .flags = BAF_TRANSITIVE,
     .export = bgp_export_local_pref,
@@ -1097,6 +1102,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_ATOMIC_AGGR] = {
     .name = "bgp_atomic_aggr",
+    .legacy_name = "BGP.atomic_aggr",
     .type = T_OPAQUE,
     .flags = BAF_TRANSITIVE,
     .encode = bgp_encode_raw,
@@ -1104,6 +1110,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_AGGREGATOR] = {
     .name = "bgp_aggregator",
+    .legacy_name = "BGP.aggregator",
     .type = T_OPAQUE,
     .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
     .encode = bgp_encode_aggregator,
@@ -1112,6 +1119,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_COMMUNITY] = {
     .name = "bgp_community",
+    .legacy_name = "BGP.community",
     .type = T_CLIST,
     .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
     .export = bgp_export_community,
@@ -1120,6 +1128,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_ORIGINATOR_ID] = {
     .name = "bgp_originator_id",
+    .legacy_name = "BGP.originator_id",
     .type = T_QUAD,
     .flags = BAF_OPTIONAL,
     .export = bgp_export_originator_id,
@@ -1128,6 +1137,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_CLUSTER_LIST] = {
     .name = "bgp_cluster_list",
+    .legacy_name = "BGP.cluster_list",
     .type = T_CLIST,
     .flags = BAF_OPTIONAL,
     .export = bgp_export_cluster_list,
@@ -1137,6 +1147,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_MP_REACH_NLRI] = {
     .name = "bgp_mp_reach_nlri",
+    .legacy_name = "BGP.mp_reach_nlri",
     .type = T_OPAQUE,
     .hidden = 1,
     .flags = BAF_OPTIONAL,
@@ -1144,6 +1155,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_MP_UNREACH_NLRI] = {
     .name = "bgp_mp_unreach_nlri",
+    .legacy_name = "BGP.mp_unreach_nlri",
     .type = T_OPAQUE,
     .hidden = 1,
     .flags = BAF_OPTIONAL,
@@ -1151,6 +1163,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_EXT_COMMUNITY] = {
     .name = "bgp_ext_community",
+    .legacy_name = "BGP.ext_community",
     .type = T_ECLIST,
     .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
     .export = bgp_export_ext_community,
@@ -1159,6 +1172,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_AS4_PATH] = {
     .name = "bgp_as4_path",
+    .legacy_name = "BGP.as4_path",
     .type = T_PATH,
     .hidden = 1,
     .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
@@ -1167,6 +1181,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_AS4_AGGREGATOR] = {
     .name = "bgp_as4_aggregator",
+    .legacy_name = "BGP.as4_aggregator",
     .type = T_OPAQUE,
     .hidden = 1,
     .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
@@ -1176,6 +1191,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_AIGP] = {
     .name = "bgp_aigp",
+    .legacy_name = "BGP.aigp",
     .type = T_OPAQUE,
     .flags = BAF_OPTIONAL | BAF_DECODE_FLAGS,
     .export = bgp_export_aigp,
@@ -1185,6 +1201,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_LARGE_COMMUNITY] = {
     .name = "bgp_large_community",
+    .legacy_name = "BGP.large_community",
     .type = T_LCLIST,
     .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
     .export = bgp_export_large_community,
@@ -1193,6 +1210,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_ONLY_TO_CUSTOMER] = {
     .name = "bgp_otc",
+    .legacy_name = "BGP.otc",
     .type = T_INT,
     .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
     .encode = bgp_encode_u32,
@@ -1200,6 +1218,7 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
   },
   [BA_MPLS_LABEL_STACK] = {
     .name = "bgp_mpls_label_stack",
+    .legacy_name = "BGP.mpls_label_stack",
     .type = T_CLIST,
     .readonly = 1,
     .export = bgp_export_mpls_label_stack,
index e10be62252f235cafcbd60b4817858badad6ab68..bde7d8051804ac6aa58592761c92b65aeea27fbe 100644 (file)
@@ -1527,22 +1527,26 @@ struct protocol proto_ospf = {
 
 struct ea_class ea_ospf_metric1 = {
   .name = "ospf_metric1",
+  .legacy_name = "OSPF.metric1",
   .type = T_INT,
 };
 
 struct ea_class ea_ospf_metric2 = {
   .name = "ospf_metric2",
+  .legacy_name = "OSPF.metric2",
   .type = T_INT,
 };
 
 struct ea_class ea_ospf_tag = {
   .name = "ospf_tag",
+  .legacy_name = "OSPF.tag",
   .type = T_INT,
   .format = ospf_tag_format,
 };
 
 struct ea_class ea_ospf_router_id = {
   .name = "ospf_router_id",
+  .legacy_name = "OSPF.router_id",
   .type = T_QUAD,
 };
 
index f574565338de90129413753eb0def8e912d93d11..8ae411dae1b683262d184ea38a6615615b559d33 100644 (file)
@@ -754,12 +754,14 @@ radv_preference_format(const eattr *a, byte *buf, uint buflen)
 
 static struct ea_class ea_radv_preference = {
   .name = "radv_preference",
+  .legacy_name = "RAdv.preference",
   .type = T_ENUM_RA_PREFERENCE,
   .format = radv_preference_format,
 };
 
 static struct ea_class ea_radv_lifetime = {
   .name = "radv_lifetime",
+  .legacy_name = "RAdv.lifetime",
   .type = T_INT,
 };
 
index ce8436156c149b173969925fe520fd14a339e22b..876d283c768d052465134245cb3c0fca3c20463a 100644 (file)
@@ -1265,11 +1265,13 @@ rip_tag_format(const eattr *a, byte *buf, uint buflen)
 
 static struct ea_class ea_rip_metric = {
   .name = "rip_metric",
+  .legacy_name = "RIP.metric",
   .type = T_INT,
 };
 
 static struct ea_class ea_rip_tag = {
   .name = "rip_tag",
+  .legacy_name = "RIP.tag",
   .type = T_INT,
   .format = rip_tag_format,
 };
index 1703a67595d5ae7957381882da07466b59875d56..784792e66e1dc78282be58d505a96d45676ca977 100644 (file)
@@ -57,50 +57,56 @@ static struct f_val krt_bitfield_empty(const struct ea_class *cls UNUSED)
 static struct ea_class
   ea_krt_prefsrc = {
     .name = "krt_prefsrc",
+    .legacy_name = "Kernel.prefsrc",
     .type = T_IP,
   },
   ea_krt_realm = {
     .name = "krt_realm",
+    .legacy_name = "Kernel.realm",
     .type = T_INT,
   },
   ea_krt_scope = {
     .name = "krt_scope",
+    .legacy_name = "Kernel.scope",
     .type = T_INT,
   };
 
 static struct ea_class ea_krt_metrics[] = {
   [RTAX_LOCK] = {
     .name = "krt_lock",
+    .legacy_name = "Kernel.lock",
     .type = T_INT,
     .format = krt_bitfield_format,
     .empty = krt_bitfield_empty,
   },
   [RTAX_FEATURES] = {
     .name = "krt_features",
+    .legacy_name = "Kernel.features",
     .type = T_INT,
     .format = krt_bitfield_format,
     .empty = krt_bitfield_empty,
   },
   [RTAX_CC_ALGO] = {
     .name = "krt_congctl",
+    .legacy_name = "Kernel.congctl",
     .type = T_STRING,
   },
-#define KRT_METRIC_INT(_rtax, _name)   [_rtax] = { .name = _name, .type = T_INT }
-  KRT_METRIC_INT(RTAX_MTU, "krt_mtu"),
-  KRT_METRIC_INT(RTAX_WINDOW, "krt_window"),
-  KRT_METRIC_INT(RTAX_RTT, "krt_rtt"),
-  KRT_METRIC_INT(RTAX_RTTVAR, "krt_rttvar"),
-  KRT_METRIC_INT(RTAX_SSTHRESH, "krt_ssthresh"),
-  KRT_METRIC_INT(RTAX_CWND, "krt_cwnd"),
-  KRT_METRIC_INT(RTAX_ADVMSS, "krt_advmss"),
-  KRT_METRIC_INT(RTAX_REORDERING, "krt_reordering"),
-  KRT_METRIC_INT(RTAX_HOPLIMIT, "krt_hoplimit"),
-  KRT_METRIC_INT(RTAX_INITCWND, "krt_initcwnd"),
-  KRT_METRIC_INT(RTAX_RTO_MIN, "krt_rto_min"),
-  KRT_METRIC_INT(RTAX_INITRWND, "krt_initrwnd"),
-  KRT_METRIC_INT(RTAX_QUICKACK, "krt_quickack"),
+#define KRT_METRIC_INT(_rtax, _name)   [_rtax] = { .name = "krt_" _name, .legacy_name = "Kernel." _name, .type = T_INT }
+  KRT_METRIC_INT(RTAX_MTU, "mtu"),
+  KRT_METRIC_INT(RTAX_WINDOW, "window"),
+  KRT_METRIC_INT(RTAX_RTT, "rtt"),
+  KRT_METRIC_INT(RTAX_RTTVAR, "rttvar"),
+  KRT_METRIC_INT(RTAX_SSTHRESH, "ssthresh"),
+  KRT_METRIC_INT(RTAX_CWND, "cwnd"),
+  KRT_METRIC_INT(RTAX_ADVMSS, "advmss"),
+  KRT_METRIC_INT(RTAX_REORDERING, "reordering"),
+  KRT_METRIC_INT(RTAX_HOPLIMIT, "hoplimit"),
+  KRT_METRIC_INT(RTAX_INITCWND, "initcwnd"),
+  KRT_METRIC_INT(RTAX_RTO_MIN, "rto_min"),
+  KRT_METRIC_INT(RTAX_INITRWND, "initrwnd"),
+  KRT_METRIC_INT(RTAX_QUICKACK, "quickack"),
 #ifdef RTAX_FASTOPEN_NO_COOKIE
-  KRT_METRIC_INT(RTAX_FASTOPEN_NO_COOKIE, "krt_fastopen_no_cookie"),
+  KRT_METRIC_INT(RTAX_FASTOPEN_NO_COOKIE, "fastopen_no_cookie"),
 #else
 #warning "Definition of RTAX_FASTOPEN_NO_COOKIE not found"
 #endif
index 42d78c6f648c5e99e0d55c0814c55e4ef12e09bf..d73446826c455f9ba5ec922b58cc22fdbaef577d 100644 (file)
@@ -141,8 +141,9 @@ cli_opts_begin: {
 };
 
 cli_opts_block:
-  /* EMPTY */ |
-  cli_opts_block RESTRICT { this_cli_config->restricted = 1; }
+  /* EMPTY */
+  | cli_opts_block RESTRICT ';' { this_cli_config->restricted = 1; }
+  | cli_opts_block V2 ATTRIBUTES ';' { this_cli_config->v2attributes = 1; }
 ;
 
 conf: THREADS expr {
index 81c073cfd056c38e43913dcd08ed02ef96cdd570..df56ca1f5dd5375190e781c3e446d265078d24fe 100644 (file)
@@ -1010,11 +1010,13 @@ krt_copy_config(struct proto_config *dest, struct proto_config *src)
 
 struct ea_class ea_krt_source = {
   .name = "krt_source",
+  .legacy_name = "Kernel.source",
   .type = T_INT,
 };
 
 struct ea_class ea_krt_metric = {
   .name = "krt_metric",
+  .legacy_name = "Kernel.metric",
   .type = T_INT,
 };