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");
{
cbor_add_string(w, "down");
server_send_byte(cbor_buf, w->pt);
+ die("Shutdown from client");
return;
}
lp_flush(lp);
{
int code;
int len = 0;
- fprintf(stdout, "got reply<%s>", x);
if (*x == '+') /* Async reply */
PRINTF(len, ">>> %s\n", x+1);
-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)
#include <stdint.h>
+#include <string.h>
+#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;
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);
}
}
}
-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
}
}
-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);
}
-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);
{
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);
}
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);
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;
--- /dev/null
+#ifndef CBOR_H
+#define CBOR_H
+#include <stdint.h>
+
+
+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
#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;
}
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;
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];
}
{
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);
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;
}
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);
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;
}
#include <stdio.h>
#include <stdlib.h>
-#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);
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);
}
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).");
}
}
+
+
+
--- /dev/null
+#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
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)
{
#include "lib/event.h"
#include "nest/route.h"
#include "conf/conf.h"
+#include "nest/cbor_shortcuts.h"
struct iface;
struct ifa;
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 */
};
#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);
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)
{
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)
{
}
}
+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),
.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)
}
}
+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",
.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
#include <stdlib.h>
#include "ospf.h"
-#include "nest/cbor_shortcuts.c"
+#include "nest/cbor_shortcuts.h"
static inline void
#include "conf/conf.h"
#include "filter/filter.h"
#include "lib/string.h"
+#include "nest/cbor_shortcuts.h"
#include "pipe.h"
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
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)
{
.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
#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
}
+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
*/
.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,
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);
}
path_control_socket_yi = "bird.ctl";
log(L_INFO "before function");
yi_init_unix(use_uid, use_gid);
- }
+ }*/
}
if (use_gid)