From: Katerina Kubecova Date: Thu, 4 Jan 2024 09:57:16 +0000 (+0100) Subject: broken includes for cbors X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9fb61e603409c06424ed3242448fa87bb04a95e2;p=thirdparty%2Fbird.git broken includes for cbors --- diff --git a/client/client.c b/client/client.c index 2149d1a0a..d782a06f9 100644 --- a/client/client.c +++ b/client/client.c @@ -169,7 +169,7 @@ void write_args_cbor(char *cmd_buffer, struct cbor_writer *w) while (l>pt) { size_t next_space = 0; - while (next_space + pt < l && cmd_buffer[next_space + pt] != ' ') + while (next_space + pt < l && cmd_buffer[next_space + pt] != ' ' && l>pt) next_space++; cbor_open_block_with_length(w, 1); cbor_add_string(w, "arg"); @@ -244,6 +244,7 @@ make_cmd_cbor(char *cmd_buffer) { cbor_add_string(w, "down"); server_send_byte(cbor_buf, w->pt); + die("Shutdown from client"); return; } lp_flush(lp); @@ -394,7 +395,6 @@ server_got_reply(char *x) { int code; int len = 0; - fprintf(stdout, "got reply<%s>", x); if (*x == '+') /* Async reply */ PRINTF(len, ">>> %s\n", x+1); diff --git a/nest/Makefile b/nest/Makefile index ef0fdf676..4db65e6ac 100644 --- a/nest/Makefile +++ b/nest/Makefile @@ -1,4 +1,4 @@ -src := a-path.c a-set.c cli.c cmds.c iface.c locks.c mpls.c neighbor.c password.c proto.c proto-build.c rt-attr.c rt-dev.c rt-fib.c rt-show.c rt-table.c +src := a-path.c a-set.c cli.c cmds.c iface.c locks.c mpls.c neighbor.c password.c proto.c proto-build.c rt-attr.c rt-dev.c rt-fib.c rt-show.c rt-table.c cbor.c cbor_shortcuts.c obj := $(src-o-files) $(all-daemon) $(cf-local) diff --git a/nest/cbor.c b/nest/cbor.c index ea26184aa..5bd136e37 100644 --- a/nest/cbor.c +++ b/nest/cbor.c @@ -1,20 +1,13 @@ #include +#include +#include "nest/cbor.h" -struct cbor_writer { - int pt; // where will next byte go - int capacity; - int8_t *cbor; - struct linpool *lp; -}; - -void write_item(struct cbor_writer *writer, uint8_t major, u64 num); +void write_item(struct cbor_writer *writer, uint8_t major, uint64_t num); void check_memory(struct cbor_writer *writer, int add_size); - - -struct cbor_writer *cbor_init(byte *buff, uint capacity, struct linpool *lp) +struct cbor_writer *cbor_init(uint8_t *buff, uint32_t capacity, struct linpool *lp) { struct cbor_writer *writer = (struct cbor_writer*)lp_alloc(lp, sizeof(struct cbor_writer)); writer->cbor = buff; @@ -44,12 +37,12 @@ void cbor_close_block_or_list(struct cbor_writer *writer) writer->pt++; } -void cbor_open_block_with_length(struct cbor_writer *writer, int length) +void cbor_open_block_with_length(struct cbor_writer *writer, uint32_t length) { write_item(writer, 5, length); } -void cbor_open_list_with_length(struct cbor_writer *writer, int length) +void cbor_open_list_with_length(struct cbor_writer *writer, uint32_t length) { write_item(writer, 4, length); } @@ -67,7 +60,7 @@ void cbor_add_int(struct cbor_writer *writer, int64_t item) } } -void cbor_add_ipv4(struct cbor_writer *writer, u32 addr) +void cbor_add_ipv4(struct cbor_writer *writer, uint32_t addr) { write_item(writer, 6, 52); // 6 is TAG, 52 is tag number for ipv4 write_item(writer, 2, 4); // bytestring of length 4 @@ -78,18 +71,22 @@ void cbor_add_ipv4(struct cbor_writer *writer, u32 addr) } } -void cbor_add_ipv6(struct cbor_writer *writer, u64 addr) +void cbor_add_ipv6(struct cbor_writer *writer, uint32_t addr[4]) { write_item(writer, 6, 54); // 6 is TAG, 54 is tag number for ipv6 - write_item(writer, 2, 8); // bytestring of length 8 - for (int i = 7; i>=0; i--) + write_item(writer, 2, 16); // bytestring of length 8 + for (int j = 0; j < 4; j++) { - writer->cbor[writer->pt] = (addr>>(i*8)) & 0xff; - writer->pt++; + for (int i = 3; i>=0; i--) + { + writer->cbor[writer->pt] = (addr[j]>>(i*8)) & 0xff; + writer->pt++; + } } } -void cbor_add_ipv4_prefix(struct cbor_writer *writer, u32 addr, int prefix) + +void cbor_add_ipv4_prefix(struct cbor_writer *writer, uint32_t addr, uint32_t prefix) { write_item(writer, 6, 52); // 6 is TAG, 52 is tag number for ipv4 cbor_open_block_with_length(writer, 2); @@ -103,7 +100,7 @@ void cbor_add_ipv4_prefix(struct cbor_writer *writer, u32 addr, int prefix) } -void cbor_add_ipv6_prefix(struct cbor_writer *writer, struct ip6_addr addr, int prefix) +void cbor_add_ipv6_prefix(struct cbor_writer *writer, uint32_t addr[4], uint32_t prefix) { write_item(writer, 6, 54); // 6 is TAG, 54 is tag number for ipv6 cbor_open_block_with_length(writer, 2); @@ -113,14 +110,14 @@ void cbor_add_ipv6_prefix(struct cbor_writer *writer, struct ip6_addr addr, int { for (int i = 3; i>=0; i--) { - writer->cbor[writer->pt] = (addr.addr[j]>>(i*8)) & 0xff; + writer->cbor[writer->pt] = (addr[j]>>(i*8)) & 0xff; writer->pt++; } } } -void cbor_add_uint(struct cbor_writer *writer, u64 item) +void cbor_add_uint(struct cbor_writer *writer, uint64_t item) { write_item(writer, 0, item); } @@ -139,7 +136,7 @@ void cbor_add_string(struct cbor_writer *writer, const char *string) writer->pt+=length; } -void cbor_nonterminated_string(struct cbor_writer *writer, const char *string, uint length) +void cbor_nonterminated_string(struct cbor_writer *writer, const char *string, uint32_t length) { write_item(writer, 3, length); // 3 is major, then goes length of string and string check_memory(writer, length); @@ -147,12 +144,12 @@ void cbor_nonterminated_string(struct cbor_writer *writer, const char *string, u writer->pt+=length; } -void write_item(struct cbor_writer *writer, uint8_t major, u64 num) +void write_item(struct cbor_writer *writer, uint8_t major, uint64_t num) { //log("write major %i %li", major, num); major = major<<5; check_memory(writer, 10); - if (num > ((u64)1<<(4*8))-1) + if (num > ((uint64_t)1<<(4*8))-1) { // We need 8 bytes to encode the num major += 0x1b; // reserving those bytes writer->cbor[writer->pt] = major; diff --git a/nest/cbor.h b/nest/cbor.h new file mode 100644 index 000000000..227ad977c --- /dev/null +++ b/nest/cbor.h @@ -0,0 +1,47 @@ +#ifndef CBOR_H +#define CBOR_H +#include + + +struct cbor_writer { + int pt; // where will next byte go + int capacity; + int8_t *cbor; + struct linpool *lp; +}; + + +struct cbor_writer *cbor_init(uint8_t *buff, uint32_t capacity, struct linpool *lp); + +void cbor_open_block(struct cbor_writer *writer); + +void cbor_open_list(struct cbor_writer *writer); + +void cbor_close_block_or_list(struct cbor_writer *writer); + +void cbor_open_block_with_length(struct cbor_writer *writer, uint32_t length); + +void cbor_open_list_with_length(struct cbor_writer *writer, uint32_t length); + + +void cbor_add_int(struct cbor_writer *writer, int64_t item); + +void cbor_add_ipv4(struct cbor_writer *writer, uint32_t addr); + +void cbor_add_ipv6(struct cbor_writer *writer, uint32_t addr[4]); + +void cbor_add_ipv4_prefix(struct cbor_writer *writer, uint32_t addr, uint32_t prefix); + + +void cbor_add_ipv6_prefix(struct cbor_writer *writer, uint32_t addr[4], uint32_t prefix); + + +void cbor_add_uint(struct cbor_writer *writer, uint64_t item); + +void cbor_add_tag(struct cbor_writer *writer, int item); + +void cbor_add_string(struct cbor_writer *writer, const char *string); + +void cbor_nonterminated_string(struct cbor_writer *writer, const char *string, uint32_t length); + +#endif diff --git a/nest/cbor_cmds.c b/nest/cbor_cmds.c index 0d3cb02b3..021b06cae 100644 --- a/nest/cbor_cmds.c +++ b/nest/cbor_cmds.c @@ -10,7 +10,7 @@ #include "proto/ospf/ospf_for_cbor.c" -uint compare_str(byte *str1, uint length, const char *str2) { +uint compare_byte_str(byte *str1, uint length, const char *str2) { if (length != strlen(str2)) { return 0; } @@ -22,8 +22,85 @@ uint compare_str(byte *str1, uint length, const char *str2) { return 1; } -int64_t preprocess_time(btime t) { - return tm_get_real_time(t) TO_S ; + +static char * +proto_state_name_stolen_for_cbor(struct proto *p) +{ + switch (p->proto_state) + { + case PS_DOWN: return p->active ? "flush" : "down"; + case PS_START: return "start"; + case PS_UP: return "up"; + case PS_STOP: return "stop"; + default: return "???"; + } +} + +void +cmd_show_protocols_cbor(byte *tbuf, uint capacity, struct arg_list *args, struct linpool *lp) +{ + log("in cmd_show_protocols_cbor"); + struct cbor_writer *w = cbor_init(tbuf, capacity, lp); + cbor_open_block_with_length(w, 1); + + cbor_add_string(w, "show_protocols:message"); + cbor_open_block_with_length(w, 2); + cbor_add_string(w, "table"); + cbor_open_list(w); + int all = 0; + int protocol = -1; + if (args->pt > 0 && compare_byte_str(args->args[0].arg, args->args[0].len, "all")) + { + all = 1; + } + + if (args->pt - all > 0) + { + protocol = all; + } + + struct proto *p; + + WALK_LIST(p, proto_list) + { + if (protocol == -1 || compare_byte_str(args->args[protocol].arg, args->args[protocol].len, p->name)) + { + cbor_open_block(w); + cbor_string_string(w, "name", p->name); + cbor_string_string(w, "proto", p->proto->name); + cbor_string_string(w, "table", p->main_channel ? p->main_channel->table->name : "---"); + cbor_string_string(w, "state", proto_state_name_stolen_for_cbor(p)); + cbor_string_int(w, "since", preprocess_time(p->last_state_change)); + byte buf[256]; + buf[0] = 0; + if (p->proto->get_status) + p->proto->get_status(p, buf); + cbor_string_string(w, "info", buf); + + if (all) + { + if (p->cf->dsc) + cbor_string_string(w, "description", p->cf->dsc); + if (p->message) + cbor_string_string(w, "message", p->message); + if (p->cf->router_id) + cbor_string_int(w, "router_id", p->cf->router_id); + if (p->vrf_set) + cbor_string_string(w, "vrf", p->vrf ? p->vrf->name : "default"); + + if (p->proto->show_proto_info_cbor) + p->proto->show_proto_info_cbor(w, p); + else + { + struct channel *c; + WALK_LIST(c, p->channels) + channel_show_info(c); + } + } + cbor_close_block_or_list(w); + } + } + cbor_close_block_or_list(w); } extern pool *rt_table_pool; @@ -122,7 +199,7 @@ int parse_show_symbols_arg(struct argument *argument) int param_vals[] = {SYM_TABLE, SYM_FILTER, SYM_FUNCTION, SYM_PROTO, SYM_TEMPLATE, SYM_CONSTANT, SYM_VARIABLE}; // defined in conf.h for (size_t j = 0; j < sizeof(params)/sizeof(char*); j++) { - if (compare_str(argument->arg, argument->len, params[j])) + if (compare_byte_str(argument->arg, argument->len, params[j])) { return param_vals[j]; } @@ -154,7 +231,7 @@ cmd_show_symbols_cbor(byte *tbuf, uint capacity, struct arg_list *args, struct l { HASH_WALK(scope->hash, next, sym) { - if (compare_str(args->args[args->pt - 1].arg, args->args[args->pt - 1].len, sym->name)) + if (compare_byte_str(args->args[args->pt - 1].arg, args->args[args->pt - 1].len, sym->name)) { cbor_add_string(w, "name"); cbor_nonterminated_string(w, args->args[args->pt - 1].arg, args->args[args->pt - 1].len); @@ -229,8 +306,8 @@ cbor_get_proto_name(struct argument *arg, enum protocol_class proto_type, struct struct proto *q; WALK_LIST(q, proto_list) { - log("%s %s %i %i %i", arg->arg, q->name, compare_str(arg->arg, arg->len, q->name) , (q->proto_state != PS_DOWN) , (q->proto->class == proto_type)); - if (compare_str(arg->arg, arg->len, q->name) && (q->proto_state != PS_DOWN) && (q->proto->class == proto_type)) + log("%s %s %i %i %i", arg->arg, q->name, compare_byte_str(arg->arg, arg->len, q->name) , (q->proto_state != PS_DOWN) , (q->proto->class == proto_type)); + if (compare_byte_str(arg->arg, arg->len, q->name) && (q->proto_state != PS_DOWN) && (q->proto->class == proto_type)) { return q; } @@ -252,15 +329,15 @@ cmd_show_ospf_cbor(byte *tbuf, uint capacity, struct arg_list *args, struct linp if (args->pt == 0) { cbor_open_block_with_length(w, 1); - cbor_string_string(w, "not implemented", "show everything about ospf"); + cbor_string_string(w, "not_implemented", "show everything about ospf"); return w->pt; } - if (compare_str(args->args[0].arg, args->args[0].len, "topology")) + if (compare_byte_str(args->args[0].arg, args->args[0].len, "topology")) { cbor_open_block(w); struct proto *proto; - int all_ospf = (args->pt > 1) && compare_str(args->args[1].arg, args->args[1].len, "all"); + int all_ospf = (args->pt > 1) && compare_byte_str(args->args[1].arg, args->args[1].len, "all"); if (args->pt - all_ospf > 1) // if there is protocol name { proto = cbor_get_proto_name(&args->args[args->pt -1], PROTOCOL_OSPF, w); @@ -280,7 +357,7 @@ cmd_show_ospf_cbor(byte *tbuf, uint capacity, struct arg_list *args, struct linp return w->pt; } else { cbor_open_block_with_length(w, 1); - cbor_add_string(w, "not implemented"); + cbor_add_string(w, "not_implemented"); cbor_nonterminated_string(w, args->args[0].arg, args->args[0].len); return w->pt; } diff --git a/nest/cbor_shortcuts.c b/nest/cbor_shortcuts.c index db10da5e3..b59e39d6b 100644 --- a/nest/cbor_shortcuts.c +++ b/nest/cbor_shortcuts.c @@ -1,9 +1,13 @@ #include #include -#include "nest/cbor.c" +#include "nest/cbor_shortcuts.h" +int64_t preprocess_time(btime t) { + return tm_get_real_time(t) TO_S ; +} + void cbor_string_string(struct cbor_writer *writer, char *key, const char *value) { cbor_add_string(writer, key); cbor_add_string(writer, value); @@ -24,7 +28,7 @@ void cbor_string_ipv4(struct cbor_writer *writer, char *key, u32 value) { cbor_add_ipv4(writer, value); } -void cbor_string_ipv6(struct cbor_writer *writer, char *key, u64 value) { +void cbor_string_ipv6(struct cbor_writer *writer, char *key, u32 value[4]) { cbor_add_string(writer, key); cbor_add_ipv6(writer, value); } @@ -57,15 +61,18 @@ void cbor_add_net(struct cbor_writer *writer, const net_addr *N) { cbor_add_ipv4_prefix(writer, n->ip4.prefix, n->ip4.pxlen); return; case NET_IP6: - cbor_add_ipv6_prefix(writer, n->ip6.prefix, n->ip6.pxlen); + cbor_add_ipv6_prefix(writer, n->ip6.prefix.addr, n->ip6.pxlen); return; case NET_VPN4: cbor_add_ipv4_prefix(writer, n->vpn4.prefix, n->vpn4.pxlen); return; case NET_VPN6: - cbor_add_ipv6_prefix(writer, n->vpn6.prefix, n->vpn6.pxlen); + cbor_add_ipv6_prefix(writer, n->vpn6.prefix.addr, n->vpn6.pxlen); return; default: bug("net type unsupported by cbor (yet)."); } } + + + diff --git a/nest/cbor_shortcuts.h b/nest/cbor_shortcuts.h new file mode 100644 index 000000000..bd9168d84 --- /dev/null +++ b/nest/cbor_shortcuts.h @@ -0,0 +1,24 @@ +#ifndef CBOR_SHORTCUTS_H +#define CBOR_SHORTCUTS_H + +#include "nest/cbor.h" +#include "sysdep/config.h" +#include "lib/birdlib.h" +#include "nest/protocol.h" +#include "lib/ip.h" + +int64_t preprocess_time(btime t); + +void cbor_string_string(struct cbor_writer *writer, char *key, const char *value); + +void cbor_string_int(struct cbor_writer *writer, char *key, int64_t value); + +void cbor_string_uint(struct cbor_writer *writer, char *key, u64 value); +void cbor_string_ipv4(struct cbor_writer *writer, char *key, u32 value); +void cbor_string_ipv6(struct cbor_writer *writer, char *key, u32 value[4]); +void cbor_named_block_two_ints(struct cbor_writer *writer, char *key, char *name1, int val1, char *name2, int val2); +void cbor_write_to_file(struct cbor_writer *writer, char *filename); + +void cbor_add_net(struct cbor_writer *writer, const net_addr *N); + +#endif diff --git a/nest/proto.c b/nest/proto.c index 9bc59f34b..ccb19bfe7 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -2136,6 +2136,106 @@ channel_show_info(struct channel *c) channel_show_stats(c); } +void +channel_show_info_cbor(struct cbor_writer *w, struct channel *c) +{ + static char *c_states[] = { "DOWN", "START", "UP", "FLUSHING" }; + cbor_add_string(w, "channel"); + cbor_open_block(w); + cbor_string_string(w, "name", c->name); + cbor_string_string(w, "state", c_states[c->channel_state]); + cbor_string_int(w, "preference", c->preference); + cbor_string_string(w, "input_filter", filter_name(c->in_filter)); + cbor_string_string(w, "output_filter", filter_name(c->out_filter)); + + if (graceful_restart_state == GRS_ACTIVE) + { + cbor_string_int(w, "gr_pending", c->gr_lock); + cbor_string_int(w, "gr_waiting", c->gr_wait); + } + + channel_show_limit_cbor(w, &c->rx_limit, "recieve_limit"); + channel_show_limit_cbor(w, &c->in_limit, "import_limit"); + channel_show_limit_cbor(w, &c->out_limit, "export_limit"); + + if (c->channel_state != CS_DOWN) + channel_show_stats_cbor(w, c); +} + +void +channel_show_stats_cbor(struct cbor_writer *w, struct channel *c) +{ + struct proto_stats *s = &c->stats; + cbor_add_string(w, "channel_stats"); + cbor_open_block(w); + + + if (c->in_keep_filtered) + { + cbor_string_int(w, "imported", s->imp_routes); + cbor_string_int(w, "filtered", s->filt_routes); + cbor_string_int(w, "exported", s->exp_routes); + cbor_string_int(w, "preffered", s->pref_routes); + } + else + { + cbor_string_int(w, "imported", s->imp_routes); + cbor_string_int(w, "exported", s->exp_routes); + cbor_string_int(w, "preffered", s->pref_routes); + } + + cbor_add_string(w, "import_updates"); + cbor_open_list_with_length(w, 5); + cbor_add_int(w, s->imp_updates_received); + cbor_add_int(w, s->imp_updates_invalid); + cbor_add_int(w, s->imp_updates_filtered); + cbor_add_int(w, s->imp_updates_ignored); + cbor_add_int(w, s->imp_updates_accepted); + + cbor_add_string(w, "import_withdraws"); + cbor_open_list_with_length(w, 5); + cbor_add_int(w, s->imp_withdraws_received); + cbor_add_int(w, s->imp_withdraws_invalid); + cbor_add_int(w, -1); + cbor_add_int(w, s->imp_withdraws_ignored); + cbor_add_int(w, s->imp_withdraws_accepted); + + cbor_add_string(w, "export_updates"); + cbor_open_list_with_length(w, 5); + cbor_add_int(w, s->exp_updates_received); + cbor_add_int(w, s->exp_updates_rejected); + cbor_add_int(w, s->exp_updates_filtered); + cbor_add_int(w, -1); + cbor_add_int(w, s->exp_updates_accepted); + + cbor_add_string(w, "import_withdraws"); + cbor_open_list_with_length(w, 5); + cbor_add_int(w, s->exp_withdraws_received); + cbor_add_int(w, -1); + cbor_add_int(w, -1); + cbor_add_int(w, -1); + cbor_add_int(w, s->exp_withdraws_accepted); + + cbor_close_block_or_list(w); +} + +void channel_show_limit_cbor(struct cbor_writer *w, struct channel_limit *l, const char *dsc) +{ + cbor_add_string(w, dsc); + cbor_open_block(w); + if (!l->action) + { + cbor_close_block_or_list(w); + return; + } + + cbor_string_int(w, "limit", l->limit); + cbor_string_int(w, "hit", l->state); + cbor_string_string(w, "action", channel_limit_name(l)); + + cbor_close_block_or_list(w); +} + void channel_cmd_debug(struct channel *c, uint mask) { diff --git a/nest/protocol.h b/nest/protocol.h index 39efba94a..aa7513e58 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -14,6 +14,7 @@ #include "lib/event.h" #include "nest/route.h" #include "conf/conf.h" +#include "nest/cbor_shortcuts.h" struct iface; struct ifa; @@ -85,6 +86,7 @@ struct protocol { void (*get_route_info)(struct rte *, byte *buf); /* Get route information (for `show route' command) */ int (*get_attr)(const struct eattr *, byte *buf, int buflen); /* ASCIIfy dynamic attribute (returns GA_*) */ void (*show_proto_info)(struct proto *); /* Show protocol info (for `show protocols all' command) */ + void (*show_proto_info_cbor)(struct cbor_writer *w, struct proto *); /* Show protocol info (for `show protocols all' command) for cbor */ void (*copy_config)(struct proto_config *, struct proto_config *); /* Copy config from given protocol instance */ }; @@ -287,7 +289,10 @@ void channel_graceful_restart_unlock(struct channel *c); #define DEFAULT_GR_WAIT 240 void channel_show_limit(struct channel_limit *l, const char *dsc); +void channel_show_limit_cbor(struct cbor_writer *w, struct channel_limit *l, const char *dsc); void channel_show_info(struct channel *c); +void channel_show_info_cbor(struct cbor_writer *w, struct channel *c); +void channel_show_stats_cbor(struct cbor_writer *w, struct channel *c); void channel_cmd_debug(struct channel *c, uint mask); void proto_cmd_show(struct proto *, uintptr_t, int); diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index f8146bdf7..0d61ee4f0 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -2406,6 +2406,28 @@ bgp_show_afis(int code, char *s, u32 *afis, uint count) cli_msg(code, b.start); } +static void +bgp_show_afis_cbor(struct cbor_writer *w, char *s, u32 *afis, uint count) +{ + cbor_add_string(w, s); + cbor_open_list(w); + for (u32 *af = afis; af < (afis + count); af++) + { + cbor_open_block(w); + const struct bgp_af_desc *desc = bgp_get_af_desc(*af); + if (desc) + cbor_string_string(w, "name", desc->name); + else + { + cbor_string_int(w, "afi", BGP_AFI(*af)); + cbor_string_int(w, "safi", BGP_SAFI(*af)); + } + cbor_close_block_or_list(w); + } + + cbor_close_block_or_list(w); +} + const char * bgp_format_role_name(u8 role) { @@ -2548,6 +2570,163 @@ bgp_show_capabilities(struct bgp_proto *p UNUSED, struct bgp_caps *caps) cli_msg(-1006, " Role: %s", bgp_format_role_name(caps->role)); } +static void +bgp_show_capabilities_cbor(struct cbor_writer *w, struct bgp_proto *p UNUSED, struct bgp_caps *caps) +{ + cbor_add_string(w, "capabilities"); + cbor_open_block(w); + struct bgp_af_caps *ac; + uint any_mp_bgp = 0; + uint any_gr_able = 0; + uint any_add_path = 0; + uint any_ext_next_hop = 0; + uint any_llgr_able = 0; + u32 *afl1 = alloca(caps->af_count * sizeof(u32)); + u32 *afl2 = alloca(caps->af_count * sizeof(u32)); + uint afn1, afn2; + + WALK_AF_CAPS(caps, ac) + { + any_mp_bgp |= ac->ready; + any_gr_able |= ac->gr_able; + any_add_path |= ac->add_path; + any_ext_next_hop |= ac->ext_next_hop; + any_llgr_able |= ac->llgr_able; + } + + if (any_mp_bgp) + { + cbor_add_string(w, "multiprotocol"); + cbor_open_block(w); + + afn1 = 0; + WALK_AF_CAPS(caps, ac) + if (ac->ready) + afl1[afn1++] = ac->afi; + + bgp_show_afis_cbor(w, "AF_announced:", afl1, afn1); + cbor_close_block_or_list(w); + } + + if (caps->route_refresh) + { + cbor_add_string(w, "route_refresh"); + cbor_open_list_with_length(w, 0); + } + + if (any_ext_next_hop) + { + afn1 = 0; + WALK_AF_CAPS(caps, ac) + if (ac->ext_next_hop) + afl1[afn1++] = ac->afi; + + bgp_show_afis_cbor(w, "IPv6_nexthop:", afl1, afn1); + } + + if (caps->ext_messages) + { + cbor_add_string(w, "extended_message"); + cbor_open_list_with_length(w, 0); + } + + if (caps->gr_aware) + { + cbor_add_string(w, "graceful_restart"); + cbor_open_list_with_length(w, 0); + } + + if (any_gr_able) + { + /* Continues from gr_aware */ + cbor_string_int(w, "restart_time", caps->gr_time); + if (caps->gr_flags & BGP_GRF_RESTART) + { + cbor_add_string(w, "restart_recovery"); + cbor_open_list_with_length(w, 0); + } + + afn1 = afn2 = 0; + WALK_AF_CAPS(caps, ac) + { + if (ac->gr_able) + afl1[afn1++] = ac->afi; + + if (ac->gr_af_flags & BGP_GRF_FORWARDING) + afl2[afn2++] = ac->afi; + } + + bgp_show_afis_cbor(w, "AF_supported", afl1, afn1); + bgp_show_afis_cbor(w, "AF_preserved", afl2, afn2); + } + + if (caps->as4_support) + { + cbor_add_string(w, "4-octet_AS_numbers"); + cbor_open_list_with_length(w, 0); + } + + if (any_add_path) + { + cli_msg(-1006, " ADD-PATH"); + + afn1 = afn2 = 0; + WALK_AF_CAPS(caps, ac) + { + if (ac->add_path & BGP_ADD_PATH_RX) + afl1[afn1++] = ac->afi; + + if (ac->add_path & BGP_ADD_PATH_TX) + afl2[afn2++] = ac->afi; + } + + bgp_show_afis_cbor(w, "add_path_RX", afl1, afn1); + bgp_show_afis_cbor(w, "add_path_TX", afl2, afn2); + } + + if (caps->enhanced_refresh) + { + cbor_add_string(w, "enhanced_refresh"); + cbor_open_list_with_length(w, 0); + } + + if (caps->llgr_aware) + { + cbor_add_string(w, "long_lived_gr"); + cbor_open_list_with_length(w, 0); + } + + if (any_llgr_able) + { + u32 stale_time = 0; + + afn1 = afn2 = 0; + WALK_AF_CAPS(caps, ac) + { + stale_time = MAX(stale_time, ac->llgr_time); + + if (ac->llgr_able && ac->llgr_time) + afl1[afn1++] = ac->afi; + + if (ac->llgr_flags & BGP_GRF_FORWARDING) + afl2[afn2++] = ac->afi; + } + + /* Continues from llgr_aware */ + cbor_string_int(w, "ll_stale_time", stale_time); + + bgp_show_afis_cbor(w, "AF_supported", afl1, afn1); + bgp_show_afis_cbor(w, "AF_preserved", afl2, afn2); + } + + if (caps->hostname) + cbor_string_string(w, "hostname", caps->hostname); + + if (caps->role != BGP_ROLE_UNDEFINED) + cbor_string_string(w, "role", bgp_format_role_name(caps->role)); + cbor_close_block_or_list(w); +} + static void bgp_show_proto_info(struct proto *P) { @@ -2662,6 +2841,155 @@ bgp_show_proto_info(struct proto *P) } } +static void +bgp_show_proto_info_cbor(struct cbor_writer *w, struct proto *P) +{ + struct bgp_proto *p = (struct bgp_proto *) P; + + cbor_add_string(w, "bgp"); + cbor_open_block(w); + + cbor_string_string(w, "state", bgp_state_dsc(p)); + + if (bgp_is_dynamic(p) && p->cf->remote_range) + { + cbor_add_string(w, "neighbor_range"); + cbor_add_net(w, p->cf->remote_range); + } + else + { + cbor_string_ipv4(w, "neighbor_addr", *p->remote_ip.addr); + cbor_string_string(w, "iface", p->cf->iface->name); + } + + if ((p->conn == &p->outgoing_conn) && (p->cf->remote_port != BGP_PORT)) + cbor_string_int(w, "neighbor_port", p->cf->remote_port); + + cbor_string_int(w, "neighbor_as", p->remote_as); + cbor_string_int(w, "local_as", p->cf->local_as); + + if (p->gr_active_num) + { + cbor_add_string(w, "gr_active"); + cbor_open_list_with_length(w, 0); + } + + if (P->proto_state == PS_START) + { + struct bgp_conn *oc = &p->outgoing_conn; + + if ((p->start_state < BSS_CONNECT) && + (tm_active(p->startup_timer))) + { + cbor_string_int(w, "error_wait_remains", tm_remains(p->startup_timer)); + cbor_string_int(w, "error_delay", p->startup_delay); + } + + if ((oc->state == BS_ACTIVE) && + (tm_active(oc->connect_timer))) + { + cbor_string_int(w, "connect_remains", tm_remains(oc->connect_timer)); + cbor_string_int(w, "connect_delay", p->cf->connect_delay_time); + } + + if (p->gr_active_num && tm_active(p->gr_timer)) + cbor_string_int(w, "restart_time", tm_remains(p->gr_timer)); + } + else if (P->proto_state == PS_UP) + { + cbor_add_string(w, "neighbor_id"); + cbor_add_ipv4(w, p->remote_id); + cli_msg(-1006, " Local capabilities"); + cbor_add_string(w, "local_cap"); + cbor_open_block_with_length(w, 1); + bgp_show_capabilities_cbor(w, p, p->conn->local_caps); + cbor_add_string(w, "neighbor_cap"); + cbor_open_block_with_length(w, 1); + bgp_show_capabilities(p, p->conn->remote_caps); + + cbor_add_string(w, "session"); + cbor_open_list(w); + if (p->is_internal) + cbor_add_string(w, "internal"); + else + cbor_add_string(w, "external"); + if (p->cf->multihop) + cbor_add_string(w, "multihop"); + if (p->rr_client) + cbor_add_string(w, "route-reflector"); + if (p->rs_client) + cbor_add_string(w, "route-server"); + if (p->as4_session) + cbor_add_string(w, "AS4"); + cbor_close_block_or_list(w); + + cbor_add_string(w, "source_address"); + cbor_add_ipv6(w, p->local_ip.addr); + + cbor_string_int(w, "hold_timer", tm_remains(p->conn->hold_timer)); + cbor_string_int(w, "hold_t_base", p->conn->hold_time); + + cbor_string_int(w, "keepalive_timer", tm_remains(p->conn->keepalive_timer)); + cbor_string_int(w, "keepalive_t_base", p->conn->keepalive_time); + } + + if ((p->last_error_class != BE_NONE) && + (p->last_error_class != BE_MAN_DOWN)) + { + const char *err1 = bgp_err_classes[p->last_error_class]; + const char *err2 = bgp_last_errmsg(p); + cli_msg(-1006, " Last error: %s%s", err1, err2); + } + + { + struct bgp_channel *c; + cbor_add_string(w, "channels"); + cbor_open_block(w); + WALK_LIST(c, p->p.channels) + { + channel_show_info_cbor(w, &c->c); + + if (c->c.channel != &channel_bgp) + continue; + + if (p->gr_active_num) + cbor_string_string(w, "neighbor_gr", bgp_gr_states[c->gr_active]); + + if (c->stale_timer && tm_active(c->stale_timer)) + cbor_string_int(w, "llstale_timer", tm_remains(c->stale_timer)); + + if (c->c.channel_state == CS_UP) + { + if (ipa_zero(c->link_addr)) + { + cbor_add_string(w, "next_hop"); + cbor_add_ipv6(w, c->next_hop_addr.addr); + } + else + { + cbor_add_string(w, "next_hop1"); + cbor_add_ipv6(w, c->next_hop_addr.addr); + cbor_add_string(w, "next_hop2"); + cbor_add_ipv6(w, c->link_addr.addr); + } + } + + if (c->igp_table_ip4) + cbor_string_string(w, "igp_ipv4_table", c->igp_table_ip4->name); + + if (c->igp_table_ip6) + cbor_string_string(w, "igp_ipv6_table", c->igp_table_ip6->name); + + if (c->base_table) + cbor_string_string(w, "base_table", c->base_table->name); + } + cbor_close_block_or_list(w); + } + cbor_close_block_or_list(w); +} + + + const struct channel_class channel_bgp = { .channel_size = sizeof(struct bgp_channel), .config_size = sizeof(struct bgp_channel_config), @@ -2689,7 +3017,8 @@ struct protocol proto_bgp = { .get_status = bgp_get_status, .get_attr = bgp_get_attr, .get_route_info = bgp_get_route_info, - .show_proto_info = bgp_show_proto_info + .show_proto_info = bgp_show_proto_info, + .show_proto_info_cbor = bgp_show_proto_info_cbor }; void bgp_build(void) diff --git a/proto/bmp/bmp.c b/proto/bmp/bmp.c index 261e9fddd..044e54073 100644 --- a/proto/bmp/bmp.c +++ b/proto/bmp/bmp.c @@ -1345,6 +1345,36 @@ bmp_show_proto_info(struct proto *P) } } +static void +bmp_show_proto_info_cbor(struct cbor_writer *w, struct proto *P) +{ + struct bmp_proto *p = (void *) P; + + cbor_add_string(w, "bmp"); + cbor_open_block(w); + + if (P->proto_state != PS_DOWN) + { + if (p->station_ip > 1<<(8*4)) + cbor_string_ipv6(w, "station_address", p->station_ip); + else + cbor_string_ipv4(w, "station_address", p->station_ip); + cbor_string_int(w, "station_port", p->station_port); + + if (!ipa_zero(p->local_addr)) + { + if (p->local_addr > 1<<(8*4)) + cbor_string_ipv6(w, "local_address", p->local_addr); + else + cbor_string_ipv4(w, "local_address", p->local_addr); + } + + if (p->sock_err) + cbor_string_int(w, "last_error", p->sock_err); + } + cbor_close_block_or_string(w); +} + struct protocol proto_bmp = { .name = "BMP", .template = "bmp%d", @@ -1358,6 +1388,7 @@ struct protocol proto_bmp = { .reconfigure = bmp_reconfigure, .get_status = bmp_get_status, .show_proto_info = bmp_show_proto_info, + .show_proto_info_cbor = bmp_show_proto_info_cbor, }; void diff --git a/proto/ospf/ospf_for_cbor.c b/proto/ospf/ospf_for_cbor.c index 4a4148ec5..feed56066 100644 --- a/proto/ospf/ospf_for_cbor.c +++ b/proto/ospf/ospf_for_cbor.c @@ -5,7 +5,7 @@ #include #include "ospf.h" -#include "nest/cbor_shortcuts.c" +#include "nest/cbor_shortcuts.h" static inline void diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c index d48ce3870..4e5bc9dcb 100644 --- a/proto/pipe/pipe.c +++ b/proto/pipe/pipe.c @@ -40,6 +40,7 @@ #include "conf/conf.h" #include "filter/filter.h" #include "lib/string.h" +#include "nest/cbor_shortcuts.h" #include "pipe.h" @@ -248,6 +249,52 @@ pipe_show_stats(struct pipe_proto *p) s2->imp_withdraws_ignored, s2->imp_withdraws_accepted); } +static void +pipe_show_stats_cbor(struct cbor_writer *w, struct pipe_proto *p) +{ + struct proto_stats *s1 = &p->pri->stats; + struct proto_stats *s2 = &p->sec->stats; + + cbor_add_string(w, "stats"); + cbor_open_block(w); + cbor_string_int(w, "imported_routes", s1->imp_routes); + cbor_string_int(w, "exported_routes", s2->imp_routes); + + cbor_add_string(w, "import_updates"); + cbor_open_list_with_length(w, 5); + cbor_add_int(w, s2->exp_updates_received); + cbor_add_int(w, s2->exp_updates_rejected + s1->imp_updates_invalid); + cbor_add_int(w, s2->exp_updates_filtered); + cbor_add_int(w, s1->imp_updates_ignored); + cbor_add_int(w, s1->imp_updates_accepted); + + cbor_add_string(w, "import_withdraws"); + cbor_open_block_with_length(w, 5); + cbor_add_int(w, s2->exp_withdraws_received); + cbor_add_int(w, s1->imp_withdraws_invalid); + cbor_add_int(w, -1); + cbor_add_int(w, s1->imp_withdraws_ignored); + cbor_add_int(w, s1->imp_withdraws_accepted); + + cbor_add_string(w, "export_updates"); + cbor_open_block_with_length(w, 5); + cbor_add_int(w, s1->exp_updates_received); + cbor_add_int(w, s1->exp_updates_rejected + s2->imp_updates_invalid); + cbor_add_int(w, s1->exp_updates_filtered); + cbor_add_int(w, s2->imp_updates_ignored); + cbor_add_int(w, s2->imp_updates_accepted); + + cbor_add_string(w, "export_withdraws"); + cbor_open_block_with_length(w, 5); + cbor_add_int(w, s1->exp_withdraws_received); + cbor_add_int(w, s2->imp_withdraws_invalid); + cbor_add_int(w, -1); + cbor_add_int(w, s2->imp_withdraws_ignored); + cbor_add_int(w, s2->imp_withdraws_accepted); + + cbor_close_block_or_list(w); +} + static const char *pipe_feed_state[] = { [ES_DOWN] = "down", [ES_FEEDING] = "feed", [ES_READY] = "up" }; static void @@ -270,6 +317,30 @@ pipe_show_proto_info(struct proto *P) pipe_show_stats(p); } + +static void +pipe_show_proto_info_cbor(struct cbor_writer *w, struct proto *P) +{ + struct pipe_proto *p = (void *) P; + cbor_add_string(w, "pipe"); + cbor_open_block(w); + + cbor_string_string(w, "table", p->pri->table->name); + cbor_string_string(w, "peer_table", p->sec->table->name); + cbor_string_string(w, "import_state", pipe_feed_state[p->sec->export_state]); + cbor_string_string(w, "export_state", pipe_feed_state[p->pri->export_state]); + cbor_string_string(w, "import_filter", filter_name(p->sec->out_filter)); + cbor_string_string(w, "export_filter", filter_name(p->pri->out_filter)); + + channel_show_limit_cbor(w, &p->pri->in_limit, "import_limit"); + channel_show_limit_cbor(w, &p->sec->in_limit, "export_limit"); + + if (P->proto_state != PS_DOWN) + pipe_show_stats_cbor(w, p); + + cbor_close_block_or_list(w); +} + void pipe_update_debug(struct proto *P) { @@ -290,7 +361,8 @@ struct protocol proto_pipe = { .reconfigure = pipe_reconfigure, .copy_config = pipe_copy_config, .get_status = pipe_get_status, - .show_proto_info = pipe_show_proto_info + .show_proto_info = pipe_show_proto_info, + .show_proto_info_cbor = pipe_show_proto_info_cbor }; void diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c index 3e321627c..35452c184 100644 --- a/proto/rpki/rpki.c +++ b/proto/rpki/rpki.c @@ -96,6 +96,7 @@ #include "rpki.h" #include "lib/string.h" #include "nest/cli.h" +#include "nest/cbor_shortcuts.h" /* Return values for reconfiguration functions */ #define NEED_RESTART 0 @@ -890,6 +891,95 @@ rpki_show_proto_info(struct proto *P) } +static void +rpki_show_proto_info_timer_cbor(struct cbor_writer *w, const char *name, uint num, timer *t) +{ + cbor_add_string(w, name); + cbor_open_block(w); + if (tm_active(t)) + { + cbor_string_int(w, "time", preprocess_time(tm_remains(t))); + cbor_string_int(w, "num", num); + } + cbor_close_block_or_list(w); +} + +static void +rpki_show_proto_info_cbor(struct cbor_writer *w, struct proto *P) +{ + struct rpki_proto *p = (struct rpki_proto *) P; + struct rpki_config *cf = (void *) p->p.cf; + struct rpki_cache *cache = p->cache; + + if (P->proto_state == PS_DOWN) + return; + + cbor_add_string(w, "rpki"); + cbor_open_block(w); + + if (cache) + { + const char *transport_name = "---"; + uint default_port = 0; + + switch (cf->tr_config.type) + { +#if HAVE_LIBSSH + case RPKI_TR_SSH: + transport_name = "SSHv2"; + default_port = RPKI_SSH_PORT; + break; +#endif + case RPKI_TR_TCP: + transport_name = "Unprotected over TCP"; + default_port = RPKI_TCP_PORT; + break; + }; + + cbor_string_string(w, "cache_server", cf->hostname); + + if (cf->port != default_port) + cbor_string_int(w, "cache_port", cf->port); + + cbor_string_string(w, "status", rpki_cache_state_to_str(cache->state)); + cbor_string_string(w, "transport", transport_name); + cbor_string_int(w, "cache_version", cache->version); + + if (cache->request_session_id) + cbor_string_string(w, "session_id", "-"); + else + cbor_string_int(w, "session_id", cache->session_id); + + if (cache->last_update) + { + cbor_string_int(w, "serial_num", cache->serial_num); + cbor_string_int(w, "last_update", preprocess_time(current_time() - cache->last_update)); + } + + rpki_show_proto_info_timer_cbor(w, "Refresh timer", cache->refresh_interval, cache->refresh_timer); + rpki_show_proto_info_timer_cbor(w, "Retry timer", cache->retry_interval, cache->retry_timer); + rpki_show_proto_info_timer_cbor(w, "Expire timer", cache->expire_interval, cache->expire_timer); + + if (p->roa4_channel) + channel_show_info_cbor(w, p->roa4_channel); + else + { + cbor_add_string(w, "no_roa4"); + cbor_open_list_with_length(w, 0); + } + + if (p->roa6_channel) + channel_show_info_cbor(w, p->roa6_channel); + else + { + cbor_add_string(w, "no_roa6"); + cbor_open_list_with_length(w, 0); + } + } + cbor_close_block_or_list(w); +} + + /* * RPKI Protocol Configuration */ @@ -959,6 +1049,7 @@ struct protocol proto_rpki = { .postconfig = rpki_postconfig, .channel_mask = (NB_ROA4 | NB_ROA6), .show_proto_info = rpki_show_proto_info, + .show_proto_info_cbor = rpki_show_proto_info_cbor, .shutdown = rpki_shutdown, .copy_config = rpki_copy_config, .reconfigure = rpki_reconfigure, diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c index 8df74bc79..a3bd8224d 100644 --- a/sysdep/unix/main.c +++ b/sysdep/unix/main.c @@ -991,8 +991,8 @@ main(int argc, char **argv) if (!parse_and_exit) { test_old_bird(path_control_socket); - //cli_init_unix(use_uid, use_gid); - if (path_control_socket_yi) + cli_init_unix(use_uid, use_gid); + /*if (path_control_socket_yi) { yi_init_unix(use_uid, use_gid); } @@ -1000,7 +1000,7 @@ main(int argc, char **argv) path_control_socket_yi = "bird.ctl"; log(L_INFO "before function"); yi_init_unix(use_uid, use_gid); - } + }*/ } if (use_gid)