mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-03 15:41:54 +00:00
cbor_parse, cbor_cmds: looks like show_status and show_symbols work (show_symbols args included)
This commit is contained in:
parent
d91390e2d2
commit
c27d43bf4c
54
nest/cbor.c
54
nest/cbor.c
@ -14,7 +14,8 @@ 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(byte *buff, uint capacity, struct linpool *lp)
|
||||||
|
{
|
||||||
struct cbor_writer *writer = (struct cbor_writer*)lp_alloc(lp, sizeof(struct cbor_writer));
|
struct cbor_writer *writer = (struct cbor_writer*)lp_alloc(lp, sizeof(struct cbor_writer));
|
||||||
writer->cbor = buff;
|
writer->cbor = buff;
|
||||||
writer->capacity = capacity;
|
writer->capacity = capacity;
|
||||||
@ -29,41 +30,50 @@ void cbor_open_block(struct cbor_writer *writer) { // We will need to close the
|
|||||||
writer->pt++;
|
writer->pt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cbor_open_list(struct cbor_writer *writer) {
|
void cbor_open_list(struct cbor_writer *writer)
|
||||||
|
{
|
||||||
check_memory(writer, 2);
|
check_memory(writer, 2);
|
||||||
writer->cbor[writer->pt] = 0x9f;
|
writer->cbor[writer->pt] = 0x9f;
|
||||||
writer->pt++;
|
writer->pt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cbor_close_block_or_list(struct cbor_writer *writer) {
|
void cbor_close_block_or_list(struct cbor_writer *writer)
|
||||||
|
{
|
||||||
check_memory(writer, 2);
|
check_memory(writer, 2);
|
||||||
writer->cbor[writer->pt] = 0xff;
|
writer->cbor[writer->pt] = 0xff;
|
||||||
writer->pt++;
|
writer->pt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cbor_open_block_with_length(struct cbor_writer *writer, int length) {
|
void cbor_open_block_with_length(struct cbor_writer *writer, int length)
|
||||||
|
{
|
||||||
write_item(writer, 5, 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, int length)
|
||||||
|
{
|
||||||
write_item(writer, 4, length);
|
write_item(writer, 4, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void cbor_add_int(struct cbor_writer *writer, int item) {
|
void cbor_add_int(struct cbor_writer *writer, int item)
|
||||||
if (item >= 0) {
|
{
|
||||||
|
if (item >= 0)
|
||||||
|
{
|
||||||
write_item(writer, 0, item); // 0 is the "major" (three bits) introducing positive int, 1 is for negative
|
write_item(writer, 0, item); // 0 is the "major" (three bits) introducing positive int, 1 is for negative
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
write_item(writer, 1, item);
|
write_item(writer, 1, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cbor_add_tag(struct cbor_writer *writer, int item) {
|
void cbor_add_tag(struct cbor_writer *writer, int item)
|
||||||
|
{
|
||||||
write_item(writer, 6, item);
|
write_item(writer, 6, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cbor_add_string(struct cbor_writer *writer, char *string) {
|
void cbor_add_string(struct cbor_writer *writer, const char *string)
|
||||||
|
{
|
||||||
int length = strlen(string);
|
int length = strlen(string);
|
||||||
write_item(writer, 3, length); // 3 is major, then goes length of string and string
|
write_item(writer, 3, length); // 3 is major, then goes length of string and string
|
||||||
check_memory(writer, length);
|
check_memory(writer, length);
|
||||||
@ -71,32 +81,38 @@ void cbor_add_string(struct cbor_writer *writer, char *string) {
|
|||||||
writer->pt+=length;
|
writer->pt+=length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_item(struct cbor_writer *writer, int8_t major, int num) {
|
void write_item(struct cbor_writer *writer, int8_t major, int num)
|
||||||
|
{
|
||||||
major = major<<5;
|
major = major<<5;
|
||||||
check_memory(writer, 10);
|
check_memory(writer, 10);
|
||||||
if (num > (1<<(2*8))-1) { // We need 4 bytes to encode the num
|
if (num > (1<<(2*8))-1)
|
||||||
|
{ // We need 4 bytes to encode the num
|
||||||
major += 0x1a; // reserving those bytes
|
major += 0x1a; // reserving those bytes
|
||||||
writer->cbor[writer->pt] = major;
|
writer->cbor[writer->pt] = major;
|
||||||
writer->pt++;
|
writer->pt++;
|
||||||
for (int i = 3; i>=0; i--) { // write n-th byte of num
|
for (int i = 3; i>=0; i--)
|
||||||
|
{ // write n-th byte of num
|
||||||
uint8_t to_write = (num>>(i*8)) & 0xff;
|
uint8_t to_write = (num>>(i*8)) & 0xff;
|
||||||
writer->cbor[writer->pt] = to_write;
|
writer->cbor[writer->pt] = to_write;
|
||||||
writer->pt++;
|
writer->pt++;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (num > (1<<(8))-1) { // We need 2 bytes to encode the num
|
if (num > (1<<(8))-1)
|
||||||
|
{ // We need 2 bytes to encode the num
|
||||||
major += 0x19; // reserving those bytes
|
major += 0x19; // reserving those bytes
|
||||||
writer->cbor[writer->pt] = major;
|
writer->cbor[writer->pt] = major;
|
||||||
writer->pt++;
|
writer->pt++;
|
||||||
for (int i = 1; i>=0; i--) { // write n-th byte of num
|
for (int i = 1; i>=0; i--)
|
||||||
|
{ // write n-th byte of num
|
||||||
uint8_t to_write = (num>>(i*8)) & 0xff;
|
uint8_t to_write = (num>>(i*8)) & 0xff;
|
||||||
writer->cbor[writer->pt] = to_write;
|
writer->cbor[writer->pt] = to_write;
|
||||||
writer->pt++;
|
writer->pt++;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (num > 23) { // byte is enough, but aditional value would be too big
|
if (num > 23)
|
||||||
|
{ // byte is enough, but aditional value would be too big
|
||||||
major += 0x18; // reserving that byte
|
major += 0x18; // reserving that byte
|
||||||
writer->cbor[writer->pt] = major;
|
writer->cbor[writer->pt] = major;
|
||||||
writer->pt++;
|
writer->pt++;
|
||||||
@ -110,8 +126,10 @@ void write_item(struct cbor_writer *writer, int8_t major, int num) {
|
|||||||
writer->pt++;
|
writer->pt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_memory(struct cbor_writer *writer, int add_size) {
|
void check_memory(struct cbor_writer *writer, int add_size)
|
||||||
if (writer->capacity - writer->pt-add_size < 0) {
|
{
|
||||||
|
if (writer->capacity - writer->pt-add_size < 0)
|
||||||
|
{
|
||||||
bug("There is not enough space for cbor response in given buffer");
|
bug("There is not enough space for cbor response in given buffer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
124
nest/cbor_cmds.c
124
nest/cbor_cmds.c
@ -5,16 +5,35 @@
|
|||||||
#include "nest/cli.h"
|
#include "nest/cli.h"
|
||||||
#include "conf/conf.h"
|
#include "conf/conf.h"
|
||||||
#include "lib/string.h"
|
#include "lib/string.h"
|
||||||
#include "lib/resource.h"
|
|
||||||
#include "filter/filter.h"
|
#include "filter/filter.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct cbor_show_data {
|
||||||
|
int type; /* Symbols type to show */
|
||||||
|
int name_length;
|
||||||
|
char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint compare_str(byte *str1, uint length, char *str2) {
|
||||||
|
if (length != strlen(str2)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < length; i++) {
|
||||||
|
if (str1[i]!=str2[i]) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extern pool *rt_table_pool;
|
extern pool *rt_table_pool;
|
||||||
extern pool *rta_pool;
|
extern pool *rta_pool;
|
||||||
extern uint *pages_kept;
|
extern uint *pages_kept;
|
||||||
|
|
||||||
uint
|
uint
|
||||||
cmd_show_memory_cbor(byte *tbuf, uint capacity) {
|
cmd_show_memory_cbor(byte *tbuf, uint capacity)
|
||||||
|
{
|
||||||
log("in cmd_show_memory_cbor");
|
log("in cmd_show_memory_cbor");
|
||||||
struct cbor_writer *w = cbor_init(tbuf, capacity, lp_new(proto_pool));
|
struct cbor_writer *w = cbor_init(tbuf, capacity, lp_new(proto_pool));
|
||||||
cbor_open_block_with_length(w, 1);
|
cbor_open_block_with_length(w, 1);
|
||||||
@ -51,3 +70,104 @@ cmd_show_memory_cbor(byte *tbuf, uint capacity) {
|
|||||||
cbor_write_to_file(w, "show_memory.cbor");
|
cbor_write_to_file(w, "show_memory.cbor");
|
||||||
return w->pt;
|
return w->pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int shutting_down;
|
||||||
|
extern int configuring;
|
||||||
|
|
||||||
|
uint
|
||||||
|
cmd_show_status_cbor(byte *tbuf, uint capacity)
|
||||||
|
{
|
||||||
|
struct cbor_writer *w = cbor_init(tbuf, capacity, lp_new(proto_pool));
|
||||||
|
cbor_open_block_with_length(w, 1);
|
||||||
|
cbor_add_string(w, "show_status:message");
|
||||||
|
|
||||||
|
cbor_open_block_with_length(w, 3);
|
||||||
|
cbor_string_string(w, "version", BIRD_VERSION);
|
||||||
|
cbor_add_string(w, "body");
|
||||||
|
cbor_open_block(w);
|
||||||
|
cbor_string_int(w, "router_id", config->router_id);
|
||||||
|
cbor_string_string(w, "hostname", config->hostname);
|
||||||
|
cbor_string_int(w, "server_time", current_time());
|
||||||
|
cbor_string_int(w, "last_reboot", boot_time);
|
||||||
|
cbor_string_int(w, "last_reconfiguration", config->load_time);
|
||||||
|
if (is_gr_active())
|
||||||
|
{
|
||||||
|
cbor_add_string(w, "gr_restart");
|
||||||
|
cbor_open_block_with_length(w, 2);
|
||||||
|
cbor_string_int(w, "waiting_for_n_channels_to_recover", get_graceful_restart_locks_num());
|
||||||
|
cbor_add_string(w, "wait_timer");
|
||||||
|
cbor_open_block_with_length(w, 2);
|
||||||
|
cbor_string_int(w, "remains", get_tm_remains_gr_wait_timer());
|
||||||
|
cbor_string_int(w, "count_time", get_config_gr_wait());
|
||||||
|
}
|
||||||
|
cbor_close_block_or_list(w);
|
||||||
|
cbor_add_string(w, "state");
|
||||||
|
if (shutting_down)
|
||||||
|
cbor_add_string(w, "Shutdown in progress");
|
||||||
|
else if (configuring)
|
||||||
|
cbor_add_string(w, "Reconfiguration in progress");
|
||||||
|
else
|
||||||
|
cbor_add_string(w, "Daemon is up and running");
|
||||||
|
cbor_write_to_file(w, "test.cbor");
|
||||||
|
return w->pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
cmd_show_symbols_cbor(byte *tbuf, uint capacity, struct cbor_show_data show)
|
||||||
|
{
|
||||||
|
struct cbor_writer *w = cbor_init(tbuf, capacity, lp_new(proto_pool));
|
||||||
|
cbor_open_block_with_length(w, 1);
|
||||||
|
cbor_add_string(w, "show_symbols:message");
|
||||||
|
cbor_open_block_with_length(w, 1);
|
||||||
|
|
||||||
|
if (show.type == -1)
|
||||||
|
{
|
||||||
|
cbor_add_string(w, "table");
|
||||||
|
cbor_open_list_with_length(w, 1);
|
||||||
|
cbor_open_block_with_length(w, 2);
|
||||||
|
|
||||||
|
for (const struct sym_scope *scope = config->root_scope; scope; scope = scope->next)
|
||||||
|
{
|
||||||
|
HASH_WALK(scope->hash, next, sym)
|
||||||
|
{
|
||||||
|
if (compare_str(show.name, show.name_length, sym->name))
|
||||||
|
{
|
||||||
|
cbor_string_string(w, "name", show.name);
|
||||||
|
cbor_string_string(w, "type", cf_symbol_class_name(sym));
|
||||||
|
return w->pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HASH_WALK_END;
|
||||||
|
}
|
||||||
|
cbor_string_string(w, "name", show.name);
|
||||||
|
cbor_string_string(w, "type", "symbol not known");
|
||||||
|
return w->pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cbor_add_string(w, "table");
|
||||||
|
cbor_open_list(w);
|
||||||
|
for (const struct sym_scope *scope = config->root_scope; scope; scope = scope->next)
|
||||||
|
HASH_WALK(scope->hash, next, sym)
|
||||||
|
{
|
||||||
|
if (!sym->scope->active)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (show.type != SYM_VOID && (sym->class != show.type))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cbor_open_block_with_length(w, 2);
|
||||||
|
cbor_string_string(w, "name", sym->name);
|
||||||
|
cbor_string_string(w, "type", cf_symbol_class_name(sym));
|
||||||
|
}
|
||||||
|
HASH_WALK_END;
|
||||||
|
|
||||||
|
cbor_close_block_or_list(w);
|
||||||
|
return w->pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#include "nest/cbor_cmds.c"
|
#include "nest/cbor_cmds.c"
|
||||||
|
|
||||||
enum functions {
|
enum functions {
|
||||||
SHOW_STATUS=0,
|
SHOW_STATUS = 0,
|
||||||
SHOW_MEMORY=1,
|
SHOW_MEMORY = 1,
|
||||||
|
SHOW_SYMBOLS = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum cbor_majors {
|
enum cbor_majors {
|
||||||
@ -28,34 +29,7 @@ struct buff_reader {
|
|||||||
uint size;
|
uint size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint compare_buff_str(struct buff_reader *buf_read, uint length, char *string) {
|
||||||
struct value
|
|
||||||
get_value(struct buff_reader *reader) {
|
|
||||||
struct value val;
|
|
||||||
byte *buff = reader->buff;
|
|
||||||
val.major = buff[reader->pt]>>5;
|
|
||||||
log("in get value");
|
|
||||||
int first_byte_val = buff[reader->pt] - (val.major<<5);
|
|
||||||
if (first_byte_val <=23) {
|
|
||||||
val.val = first_byte_val;
|
|
||||||
reader->pt++;
|
|
||||||
} else if (first_byte_val == 0x18) {
|
|
||||||
val.val = buff[reader->pt+1];
|
|
||||||
reader->pt+=2;
|
|
||||||
} else if (first_byte_val == 0x19) {
|
|
||||||
val.val = buff[reader->pt+1]>>8 + buff[reader->pt+2];
|
|
||||||
reader->pt+=3;
|
|
||||||
} else if (first_byte_val == 0x1a) {
|
|
||||||
val.val = buff[reader->pt+1]>>24 + buff[reader->pt+2]>>16 + buff[reader->pt+3]>>8 + buff[reader->pt+4];
|
|
||||||
reader->pt+=5;
|
|
||||||
} else if (first_byte_val == 0xff) {
|
|
||||||
val.val = -1;
|
|
||||||
reader->pt++;
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint compare_str(struct buff_reader *buf_read, uint length, char *string) {
|
|
||||||
if (length != strlen(string)) {
|
if (length != strlen(string)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -67,37 +41,164 @@ uint compare_str(struct buff_reader *buf_read, uint length, char *string) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int val_is_break(struct value val) {
|
struct value
|
||||||
|
get_value(struct buff_reader *reader)
|
||||||
|
{
|
||||||
|
struct value val;
|
||||||
|
byte *buff = reader->buff;
|
||||||
|
val.major = buff[reader->pt]>>5;
|
||||||
|
log("in get value");
|
||||||
|
int first_byte_val = buff[reader->pt] - (val.major<<5);
|
||||||
|
if (first_byte_val <=23) {
|
||||||
|
val.val = first_byte_val;
|
||||||
|
reader->pt++;
|
||||||
|
} else if (first_byte_val == 0x18)
|
||||||
|
{
|
||||||
|
val.val = buff[reader->pt+1];
|
||||||
|
reader->pt+=2;
|
||||||
|
} else if (first_byte_val == 0x19)
|
||||||
|
{
|
||||||
|
val.val = buff[reader->pt+1]>>8 + buff[reader->pt+2];
|
||||||
|
reader->pt+=3;
|
||||||
|
} else if (first_byte_val == 0x1a)
|
||||||
|
{
|
||||||
|
val.val = buff[reader->pt+1]>>24 + buff[reader->pt+2]>>16 + buff[reader->pt+3]>>8 + buff[reader->pt+4];
|
||||||
|
reader->pt+=5;
|
||||||
|
} else if (first_byte_val == 0xff)
|
||||||
|
{
|
||||||
|
val.val = -1;
|
||||||
|
reader->pt++;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int val_is_break(struct value val)
|
||||||
|
{
|
||||||
return val.major == FLOAT && val.val == -1; // break code is 0xff, so the major is same for float and break
|
return val.major == FLOAT && val.val == -1; // break code is 0xff, so the major is same for float and break
|
||||||
}
|
}
|
||||||
|
|
||||||
uint
|
void skip_optional_args(struct buff_reader *rbuf_read, int items_in_block)
|
||||||
do_command(struct buff_reader *rbuf_read, struct buff_reader *tbuf_read, int items_in_block) {
|
{
|
||||||
struct value val= get_value(rbuf_read);
|
// We are skipping sequence <"args":{}> or empty sequence <>. It can might empty in block length 1 (items_in_block == 0), or undefined length block. "args" might be empty the same way.
|
||||||
ASSERT(val.major == UINT);
|
if (items_in_block == 0)
|
||||||
switch (val.val)
|
|
||||||
{
|
{
|
||||||
case SHOW_MEMORY:
|
return;
|
||||||
if (items_in_block != 0) {
|
}
|
||||||
val = get_value(rbuf_read);
|
struct value val = get_value(rbuf_read);
|
||||||
if (val.major == TEXT) { //Since the list args is optional, we need to know if it is here and check if it is empty.
|
if (val.major == TEXT)
|
||||||
ASSERT(compare_str(rbuf_read, val.val, "args"));
|
{ //Since the list args is optional, we need to know if it is here and check if it is empty.
|
||||||
|
ASSERT(compare_buff_str(rbuf_read, val.val, "args"));
|
||||||
rbuf_read->pt+=val.val;
|
rbuf_read->pt+=val.val;
|
||||||
val = get_value(rbuf_read);
|
val = get_value(rbuf_read);
|
||||||
ASSERT(val.major == ARRAY);
|
ASSERT(val.major == ARRAY);
|
||||||
ASSERT(val.val <=0);
|
ASSERT(val.val <=0);
|
||||||
if (val.val ==-1) { // list open with unspecified size, but we know there should be none for show memory (but, of course, we know it because of the show memory function, not because of yang)
|
if (val.val ==-1)
|
||||||
|
{ // list open with unspecified size, but we know there should be none for show memory (but, of course, we know it because of the show memory function, not because of yang)
|
||||||
val = get_value(rbuf_read);
|
val = get_value(rbuf_read);
|
||||||
ASSERT(val_is_break(val));
|
ASSERT(val_is_break(val));
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
ASSERT(items_in_block == -1); // assert the block was not open to exactly two items (we do not have args list and there is no chance to have another item in the block)
|
{
|
||||||
|
ASSERT(items_in_block == -1); // assert the block was not open to exact num of items, because it cant be just for command (we would returned) and we did not find more items.
|
||||||
|
rbuf_read->pt--; // we read one byte from future, we need to shift pointer back. The val should be break, but we are not going to close the block, because it was not opened here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void parse_show_symbols_args(struct buff_reader *rbuf_read, int items_in_block, struct cbor_show_data *arg)
|
||||||
|
{
|
||||||
|
log("parse symbols args");
|
||||||
|
char *params[] = {"table", "filter", "function", "protocol", "template"};
|
||||||
|
int param_vals[] = {SYM_TABLE, SYM_FILTER, SYM_FUNCTION, SYM_PROTO, SYM_TEMPLATE}; // defined in conf.h
|
||||||
|
arg->type = SYM_VOID; // default option
|
||||||
|
arg->name = NULL;
|
||||||
|
if (items_in_block == 0)
|
||||||
|
{ // there should not be arg array
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct value val = get_value(rbuf_read);
|
||||||
|
if (val.major == TEXT)
|
||||||
|
{
|
||||||
|
log("text");
|
||||||
|
ASSERT(compare_buff_str(rbuf_read, val.val, "args"));
|
||||||
|
log("args");
|
||||||
|
rbuf_read->pt+=val.val;
|
||||||
|
val = get_value(rbuf_read);
|
||||||
|
ASSERT(val.major == ARRAY);
|
||||||
|
int num_array_items = val.val;
|
||||||
|
log("num arr items %i", num_array_items);
|
||||||
|
for (int i = 0; i<num_array_items || (num_array_items == -1 && !val_is_break(val)); i++)
|
||||||
|
{
|
||||||
|
// There will be only one argument in struct cbor_show_data arg after parsing the array of args. Current bird cli is behaving this way too.
|
||||||
|
val = get_value(rbuf_read);
|
||||||
|
if (val_is_break(val))
|
||||||
|
{
|
||||||
|
rbuf_read->pt--;
|
||||||
|
}
|
||||||
|
else if (val.major == BLOCK)
|
||||||
|
{
|
||||||
|
int wait_close = val.val == -1;
|
||||||
|
if (!wait_close)
|
||||||
|
{
|
||||||
|
ASSERT(val.val==1);
|
||||||
|
}
|
||||||
|
val = get_value(rbuf_read);
|
||||||
|
ASSERT(compare_buff_str(rbuf_read, val.val, "arg"));
|
||||||
|
rbuf_read->pt+=val.val;
|
||||||
|
val = get_value(rbuf_read);
|
||||||
|
ASSERT(val.major == TEXT);
|
||||||
|
int found = 0;
|
||||||
|
for (size_t j = 0; j < sizeof(params)/sizeof(char*) && found == 0; j++)
|
||||||
|
{
|
||||||
|
if (compare_buff_str(rbuf_read, val.val, params[j]))
|
||||||
|
{
|
||||||
|
arg->type = param_vals[j];
|
||||||
|
found = 1;
|
||||||
|
log("found %s, on %i val %i", params[j], j, param_vals[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found == 0)
|
||||||
|
{
|
||||||
|
arg->type = -1;
|
||||||
|
arg->name = rbuf_read->buff + rbuf_read->pt;
|
||||||
|
arg->name_length = val.val;
|
||||||
|
}
|
||||||
|
rbuf_read->pt+=val.val;
|
||||||
|
if (wait_close)
|
||||||
|
{
|
||||||
|
val = get_value(rbuf_read);
|
||||||
|
ASSERT(val_is_break(val));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
ASSERT(items_in_block == -1); // assert the block was not open to exact num of items, because it cant be just for command (we would returned) and we did not find more items.
|
||||||
rbuf_read->pt--; // we read one byte from future, we need to shift pointer back
|
rbuf_read->pt--; // we read one byte from future, we need to shift pointer back
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint
|
||||||
|
do_command(struct buff_reader *rbuf_read, struct buff_reader *tbuf_read, int items_in_block)
|
||||||
|
{
|
||||||
|
struct value val = get_value(rbuf_read);
|
||||||
|
ASSERT(val.major == UINT);
|
||||||
|
switch (val.val)
|
||||||
|
{
|
||||||
|
case SHOW_MEMORY:
|
||||||
|
skip_optional_args(rbuf_read, items_in_block);
|
||||||
return cmd_show_memory_cbor(tbuf_read->buff, tbuf_read->size);
|
return cmd_show_memory_cbor(tbuf_read->buff, tbuf_read->size);
|
||||||
case SHOW_STATUS:
|
case SHOW_STATUS:
|
||||||
return 0;
|
skip_optional_args(rbuf_read, items_in_block);
|
||||||
|
return cmd_show_status_cbor(tbuf_read->buff, tbuf_read->size);
|
||||||
|
case SHOW_SYMBOLS:
|
||||||
|
struct cbor_show_data arg;
|
||||||
|
parse_show_symbols_args(rbuf_read, items_in_block, &arg);
|
||||||
|
return cmd_show_symbols_cbor(tbuf_read->buff, tbuf_read->size, arg);
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -105,7 +206,8 @@ do_command(struct buff_reader *rbuf_read, struct buff_reader *tbuf_read, int ite
|
|||||||
|
|
||||||
|
|
||||||
uint
|
uint
|
||||||
parse_cbor(uint size, byte *rbuf, byte *tbuf, uint tbsize) {
|
parse_cbor(uint size, byte *rbuf, byte *tbuf, uint tbsize)
|
||||||
|
{
|
||||||
log("cbor parse");
|
log("cbor parse");
|
||||||
struct buff_reader rbuf_read;
|
struct buff_reader rbuf_read;
|
||||||
struct buff_reader tbuf_read;
|
struct buff_reader tbuf_read;
|
||||||
@ -116,18 +218,21 @@ parse_cbor(uint size, byte *rbuf, byte *tbuf, uint tbsize) {
|
|||||||
rbuf_read.pt = 0;
|
rbuf_read.pt = 0;
|
||||||
tbuf_read.pt = 0;
|
tbuf_read.pt = 0;
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
struct value val = get_value(&rbuf_read);
|
struct value val = get_value(&rbuf_read);
|
||||||
ASSERT(val.major == BLOCK);
|
ASSERT(val.major == BLOCK);
|
||||||
ASSERT(val.val <=1);
|
ASSERT(val.val <=1);
|
||||||
int wait_for_end_main_block = val.val == -1;
|
int wait_for_end_main_block = val.val == -1;
|
||||||
if (val.val != 0) {
|
if (val.val != 0)
|
||||||
|
{
|
||||||
val = get_value(&rbuf_read);
|
val = get_value(&rbuf_read);
|
||||||
if ( !( wait_for_end_main_block == -1 && val_is_break(val) )) {
|
if ( !( wait_for_end_main_block == -1 && val_is_break(val) ))
|
||||||
|
{
|
||||||
ASSERT(val.major == TEXT);
|
ASSERT(val.major == TEXT);
|
||||||
ASSERT(compare_str(&rbuf_read, val.val, "command:do"));
|
ASSERT(compare_buff_str(&rbuf_read, val.val, "command:do")); // this should be mandatory in yang, but when i marked it mandatory, it destroyed all other yangs (required command in all other modules)
|
||||||
rbuf_read.pt+=val.val;
|
rbuf_read.pt+=val.val;
|
||||||
|
|
||||||
val = get_value(&rbuf_read);
|
val = get_value(&rbuf_read);
|
||||||
@ -138,11 +243,12 @@ parse_cbor(uint size, byte *rbuf, byte *tbuf, uint tbsize) {
|
|||||||
val = get_value(&rbuf_read);
|
val = get_value(&rbuf_read);
|
||||||
ASSERT(val.major == TEXT);
|
ASSERT(val.major == TEXT);
|
||||||
items_in_block--;
|
items_in_block--;
|
||||||
ASSERT(compare_str(&rbuf_read, val.val, "command"));
|
ASSERT(compare_buff_str(&rbuf_read, val.val, "command"));
|
||||||
rbuf_read.pt+=val.val;
|
rbuf_read.pt+=val.val;
|
||||||
|
|
||||||
tbuf_read.pt = do_command(&rbuf_read, &tbuf_read, items_in_block);
|
tbuf_read.pt = do_command(&rbuf_read, &tbuf_read, items_in_block);
|
||||||
if (items_in_block == -1) {
|
if (items_in_block == -1)
|
||||||
|
{
|
||||||
val = get_value(&rbuf_read);
|
val = get_value(&rbuf_read);
|
||||||
ASSERT(val.major == FLOAT && val.val == -1);
|
ASSERT(val.major == FLOAT && val.val == -1);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "nest/cbor.c"
|
#include "nest/cbor.c"
|
||||||
|
|
||||||
|
|
||||||
void cbor_string_string(struct cbor_writer *writer, char *key, char *value) {
|
void cbor_string_string(struct cbor_writer *writer, char *key, const char *value) {
|
||||||
cbor_add_string(writer, key);
|
cbor_add_string(writer, key);
|
||||||
cbor_add_string(writer, value);
|
cbor_add_string(writer, value);
|
||||||
}
|
}
|
||||||
|
27
nest/cmds.c
27
nest/cmds.c
@ -42,33 +42,6 @@ cmd_show_status(void)
|
|||||||
cli_msg(13, "Reconfiguration in progress");
|
cli_msg(13, "Reconfiguration in progress");
|
||||||
else
|
else
|
||||||
cli_msg(13, "Daemon is up and running");
|
cli_msg(13, "Daemon is up and running");
|
||||||
|
|
||||||
|
|
||||||
/*struct cbor_writer *w = cbor_init(lp_new(proto_pool), 1000);
|
|
||||||
cbor_open_block_with_length(w, 1);
|
|
||||||
cbor_add_string(w, "show_status:message");
|
|
||||||
|
|
||||||
cbor_open_block_with_length(w, 3);
|
|
||||||
cbor_string_string(w, "BIRD", BIRD_VERSION);
|
|
||||||
cbor_add_string(w, "body");
|
|
||||||
cbor_open_block(w);
|
|
||||||
cbor_string_int(w, "router_id", config->router_id);
|
|
||||||
cbor_string_string(w, "hostname", config->hostname);
|
|
||||||
cbor_string_string(w, "server_time", current_time());
|
|
||||||
tm_format_time(time, &config->tf_base, boot_time);
|
|
||||||
cbor_string_int(w, "last_reboot", boot_time);
|
|
||||||
cbor_string_string(w, "last_reconfiguration", config->load_time);
|
|
||||||
|
|
||||||
// TODO graceful restart
|
|
||||||
cbor_close_block_or_list(w);
|
|
||||||
cbor_add_string(w, "state");
|
|
||||||
if (shutting_down)
|
|
||||||
cbor_add_string(w, "Shutdown in progress");
|
|
||||||
else if (configuring)
|
|
||||||
cbor_add_string(w, "Reconfiguration in progress");
|
|
||||||
else
|
|
||||||
cbor_add_string(w, "Daemon is up and running");
|
|
||||||
cbor_write_to_file(w, "test.cbor");*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
24
nest/proto.c
24
nest/proto.c
@ -1630,6 +1630,30 @@ graceful_restart_show_status(void)
|
|||||||
cli_msg(-24, " Wait timer is %t/%u", tm_remains(gr_wait_timer), config->gr_wait);
|
cli_msg(-24, " Wait timer is %t/%u", tm_remains(gr_wait_timer), config->gr_wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
is_gr_active(void)
|
||||||
|
{
|
||||||
|
return graceful_restart_state == GRS_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
get_graceful_restart_locks_num(void)
|
||||||
|
{
|
||||||
|
return graceful_restart_locks;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
get_tm_remains_gr_wait_timer(void)
|
||||||
|
{
|
||||||
|
return tm_remains(gr_wait_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
get_config_gr_wait(void)
|
||||||
|
{
|
||||||
|
return config->gr_wait;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* channel_graceful_restart_lock - lock graceful restart by channel
|
* channel_graceful_restart_lock - lock graceful restart by channel
|
||||||
* @p: channel instance
|
* @p: channel instance
|
||||||
|
@ -277,6 +277,10 @@ void proto_set_message(struct proto *p, char *msg, int len);
|
|||||||
void graceful_restart_recovery(void);
|
void graceful_restart_recovery(void);
|
||||||
void graceful_restart_init(void);
|
void graceful_restart_init(void);
|
||||||
void graceful_restart_show_status(void);
|
void graceful_restart_show_status(void);
|
||||||
|
int is_gr_active(void);
|
||||||
|
int get_graceful_restart_locks_num(void);
|
||||||
|
int get_tm_remains_gr_wait_timer(void);
|
||||||
|
int get_config_gr_wait(void);
|
||||||
void channel_graceful_restart_lock(struct channel *c);
|
void channel_graceful_restart_lock(struct channel *c);
|
||||||
void channel_graceful_restart_unlock(struct channel *c);
|
void channel_graceful_restart_unlock(struct channel *c);
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
¡jcommand:do¢gcommanddargs€
|
¡jcommand:do¢gcommanddargs<67>¡carghprotocol
|
@ -1,2 +1,2 @@
|
|||||||
{"command:do":{"command": 1, "args":[]}}
|
{"command:do":{"command": 2, "args":[{"arg":"protocol"}]}}
|
||||||
|
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
module command {
|
module command {
|
||||||
|
|
||||||
namespace ".";
|
namespace "command";
|
||||||
|
|
||||||
prefix "command";
|
prefix "command";
|
||||||
|
|
||||||
container do {
|
container do {
|
||||||
leaf command {
|
leaf command {
|
||||||
mandatory true;
|
|
||||||
type uint32;
|
type uint32;
|
||||||
}
|
}
|
||||||
list args {
|
list args {
|
||||||
|
Binary file not shown.
@ -1,31 +1,13 @@
|
|||||||
{
|
{
|
||||||
"show_memory:message": {
|
"show_status:message": {
|
||||||
"header": "BIRD memory usage",
|
"version": "v2.14-23-gd91390e2-x",
|
||||||
"body": {
|
"body": {
|
||||||
"routing_tables": {
|
"router_id": 167772417,
|
||||||
"effective": 34604,
|
"hostname": "kkubecova-ntb",
|
||||||
"overhead": 2848
|
"server_time": 208154921,
|
||||||
|
"last_reboot": 197746045,
|
||||||
|
"last_reconfiguration": 197746045
|
||||||
},
|
},
|
||||||
"route_attributes": {
|
"state": "Daemon is up and running"
|
||||||
"effective": 26826,
|
|
||||||
"overhead": 13448
|
|
||||||
},
|
|
||||||
"protocols": {
|
|
||||||
"effective": 63564,
|
|
||||||
"overhead": 15312
|
|
||||||
},
|
|
||||||
"current_config": {
|
|
||||||
"effective": 299744,
|
|
||||||
"overhead": 2152
|
|
||||||
},
|
|
||||||
"standby_memory": {
|
|
||||||
"effective": 0,
|
|
||||||
"overhead": 348160
|
|
||||||
},
|
|
||||||
"total": {
|
|
||||||
"effective": 506754,
|
|
||||||
"overhead": 388960
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,7 +2,7 @@ module show_status {
|
|||||||
|
|
||||||
namespace ".";
|
namespace ".";
|
||||||
|
|
||||||
prefix "status";
|
prefix "show_status";
|
||||||
|
|
||||||
description "cli show status format";
|
description "cli show status format";
|
||||||
|
|
||||||
@ -15,40 +15,33 @@ module show_status {
|
|||||||
|
|
||||||
grouping timer {
|
grouping timer {
|
||||||
leaf remains {
|
leaf remains {
|
||||||
type decimal64 {
|
type uint64;
|
||||||
fraction-digits 3;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
leaf count_time {
|
leaf count_time {
|
||||||
type uint32;
|
type uint64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
container message {
|
container message {
|
||||||
container header {
|
|
||||||
leaf bird {
|
|
||||||
type string;
|
|
||||||
}
|
|
||||||
leaf version {
|
leaf version {
|
||||||
type string;
|
type string;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
container body {
|
container body {
|
||||||
leaf router_id {
|
leaf router_id {
|
||||||
type string;
|
type int32;
|
||||||
}
|
}
|
||||||
leaf hostname {
|
leaf hostname {
|
||||||
type string;
|
type string;
|
||||||
}
|
}
|
||||||
leaf server_time {
|
leaf server_time {
|
||||||
type date-and-time;
|
type int32;
|
||||||
}
|
}
|
||||||
leaf last_reboot {
|
leaf last_reboot {
|
||||||
type date-and-time;
|
type int32;
|
||||||
}
|
}
|
||||||
leaf last_reconfiguration {
|
leaf last_reconfiguration {
|
||||||
type date-and-time;
|
type int32;
|
||||||
}
|
}
|
||||||
container gr_restart {
|
container gr_restart {
|
||||||
leaf waiting_for_n_channels_to_recover {
|
leaf waiting_for_n_channels_to_recover {
|
||||||
|
1
yang/show_symbols.cbor
Normal file
1
yang/show_symbols.cbor
Normal file
@ -0,0 +1 @@
|
|||||||
|
ˇtshow_symbols:messageˇetableź˘dnamegebgp4_1dtypehprotocol˘dnamegebgp6_1dtypehprotocol˘dnamegebgp4_2dtypehprotocol˘dnamegebgp6_2dtypehprotocol˘dnamegstatic6dtypehprotocol˘dnamegstatic4dtypehprotocol˘dnamegkernel6dtypehprotocol˘dnamegkernel4dtypehprotocol˘dnamegdevice1dtypehprotocol˙
|
@ -14,6 +14,12 @@
|
|||||||
"revision": "",
|
"revision": "",
|
||||||
"conformance-type": "implement"
|
"conformance-type": "implement"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "show_symbols",
|
||||||
|
"namespace": "https://bird.nic.cz/yang/v2.15/cli-debug",
|
||||||
|
"revision": "",
|
||||||
|
"conformance-type": "implement"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "show_protocols",
|
"name": "show_protocols",
|
||||||
"namespace": "https://bird.nic.cz/yang/v2.15/cli-debug",
|
"namespace": "https://bird.nic.cz/yang/v2.15/cli-debug",
|
||||||
|
Loading…
Reference in New Issue
Block a user