0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2025-01-02 23:21:54 +00:00

CLI: v2 compatibility mode for attribute name display

Also fixed display of bgp_otc (was just "otc" before).
This commit is contained in:
Maria Matejka 2024-12-18 12:24:49 +01:00
parent c3c12e1b4f
commit 4c59e20968
14 changed files with 99 additions and 28 deletions

View 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">

View 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 */ \

View 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;
}

View 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"

View 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

View 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);

View 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,

View 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,
@ -1192,7 +1209,8 @@ static union bgp_attr_desc bgp_attr_table[BGP_ATTR_MAX] = {
.decode = bgp_decode_large_community,
},
[BA_ONLY_TO_CUSTOMER] = {
.name = "otc",
.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,

View 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,
};

View 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,
};

View 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,
};

View 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

View 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 {

View File

@ -986,11 +986,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,
};