]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
cbor.c: primitive tools for writing cbor
authorKaterina Kubecova <katerina.kubecova@nic.cz>
Thu, 23 Nov 2023 07:52:51 +0000 (08:52 +0100)
committerKaterina Kubecova <katerina.kubecova@nic.cz>
Thu, 23 Nov 2023 07:52:51 +0000 (08:52 +0100)
nest/cbor.c [new file with mode: 0644]
nest/cbor_shortcuts.c [new file with mode: 0644]
nest/cmds.c
yang/show_status.yang

diff --git a/nest/cbor.c b/nest/cbor.c
new file mode 100644 (file)
index 0000000..418d32f
--- /dev/null
@@ -0,0 +1,114 @@
+#include <stdint.h>
+
+
+
+struct cbor_writer {
+  int pt; // where will next byte go
+  int capacity;
+  struct linpool *lp;
+  int8_t *cbor;
+};
+
+void write_item(struct cbor_writer *writer, int8_t major, int num);
+void check_memory(struct cbor_writer *writer, int add_size);
+
+
+
+struct cbor_writer *cbor_init(struct linpool *lp, int size_guess) {
+  struct cbor_writer *writer = (struct cbor_writer *) lp_alloc(lp, sizeof(struct cbor_writer));
+  writer->cbor = lp_alloc(lp, size_guess * sizeof(int8_t));
+  writer->capacity = size_guess;
+  writer->lp = lp;
+  writer->pt =0;
+  return writer;
+}
+  
+void cbor_open_block(struct cbor_writer *writer) { // We will need to close the block later manualy
+  check_memory(writer, 2);
+  writer->cbor[writer->pt] = 0xbf;
+  writer->pt++;
+}
+
+void cbor_open_list(struct cbor_writer *writer) {
+  check_memory(writer, 2);
+  writer->cbor[writer->pt] = 0x9f;
+  writer->pt++;
+}
+
+void cbor_close_block_or_list(struct cbor_writer *writer) {
+  check_memory(writer, 2);
+  writer->cbor[writer->pt] = 0xff;
+  writer->pt++;
+}
+
+void cbor_open_block_with_length(struct cbor_writer *writer, int length) {
+  write_item(writer, 5, length);
+}
+
+void cbor_open_list_with_length(struct cbor_writer *writer, int length) {
+  write_item(writer, 4, length);
+}
+
+
+void cbor_add_int(struct cbor_writer *writer, int item) {
+  if (item >= 0) {
+    write_item(writer, 0, item); // 0 is the "major" (three bits) introducing positive int, 1 is for negative
+  }
+  else {
+    write_item(writer, 1, item);
+  }
+}
+void cbor_add_string(struct cbor_writer *writer, char *string) {
+  int length = strlen(string);
+  write_item(writer, 3, length);  // 3 is major, then goes length of string and string
+  check_memory(writer, length);
+  memcpy(writer->cbor+writer->pt, string, length);
+  writer->pt+=length;
+}
+
+void write_item(struct cbor_writer *writer, int8_t major, int num) {
+  major = major<<5;
+  check_memory(writer, 10);
+  if (num > (1<<(2*8))-1) { // We need 4 bytes to encode the num
+    major += 0x1a; // reserving those bytes
+    writer->cbor[writer->pt] = major;
+    writer->pt++;
+    for (int i = 3; i>=0; i--) { // write n-th byte of num
+      uint8_t to_write = (num>>(i*8)) & 0xff;
+      writer->cbor[writer->pt] = to_write;
+      writer->pt++;
+    }
+    return;
+  }
+  if (num > (1<<(8))-1) { // We need 2 bytes to encode the num
+    major += 0x19; // reserving those bytes
+    writer->cbor[writer->pt] = major;
+    writer->pt++;
+    for (int i = 1; i>=0; i--) { // write n-th byte of num
+      uint8_t to_write = (num>>(i*8)) & 0xff;
+      writer->cbor[writer->pt] = to_write;
+      writer->pt++;
+    }
+    return;
+  }
+  if (num > 23) { // byte is enough, but aditional value would be too big
+    major += 0x18; // reserving those bytes
+    writer->cbor[writer->pt] = major;
+    writer->pt++;
+    uint8_t to_write = num & 0xff;
+    writer->cbor[writer->pt] = to_write;
+    writer->pt++;
+    return;
+  }
+  major += num;  // we can store the num as additional value 
+  writer->cbor[writer->pt] = major;
+  writer->pt++;
+}
+
+void check_memory(struct cbor_writer *writer, int add_size) {
+  if (writer->capacity - writer->pt-add_size < 0) {
+    int8_t *a = writer->cbor;
+    writer->cbor = lp_alloc(writer->lp, writer->capacity*2);
+    memcpy(writer->cbor, a, writer->pt);
+  }
+}
diff --git a/nest/cbor_shortcuts.c b/nest/cbor_shortcuts.c
new file mode 100644 (file)
index 0000000..d60a124
--- /dev/null
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "nest/cbor.c"
+
+
+void cbor_string_string(struct cbor_writer *writer, char *key, char *value) {
+  cbor_add_string(writer, key);
+  cbor_add_string(writer, value);
+}
+
+void cbor_named_block_two_ints(struct cbor_writer *writer, char *key, char *name1, int val1, char *name2, int val2) {
+  cbor_add_string(writer, key);
+  cbor_open_block_with_length(writer, 2);
+  cbor_add_string(writer, name1);
+  cbor_add_int(writer, val1);
+  cbor_add_string(writer, name2);
+  cbor_add_int(writer, val2);
+}
+
+void cbor_write_to_file(struct cbor_writer *writer, char *filename) {
+  FILE *write_ptr;
+
+  write_ptr = fopen(filename, "wb");
+
+  fwrite(writer->cbor, writer->pt, 1, write_ptr);
+  fclose(write_ptr);
+}
+
index d49bbc53c32384454d7f38f8537142943adbe365..4562262ae5133a6d5124f38f7dd4f70e88396284 100644 (file)
@@ -15,6 +15,7 @@
 #include "lib/string.h"
 #include "lib/resource.h"
 #include "filter/filter.h"
+#include "nest/cbor_shortcuts.c"
 
 extern int shutting_down;
 extern int configuring;
@@ -26,7 +27,7 @@ cmd_show_status(void)
 
   cli_msg(-1000, "BIRD " BIRD_VERSION);
   tm_format_time(tim, &config->tf_base, current_time());
-  cli_msg(-1011, "Router ID is %R", config->router_id);
+  cli_msg(-1011, "Router ID is %R  %i    %x", config->router_id, config->router_id, config->router_id);
   cli_msg(-1011, "Hostname is %s", config->hostname);
   cli_msg(-1011, "Current server time is %s", tim);
   tm_format_time(tim, &config->tf_base, boot_time);
@@ -42,6 +43,34 @@ cmd_show_status(void)
     cli_msg(13, "Reconfiguration in progress");
   else
     cli_msg(13, "Daemon is up and running");
+
+
+  byte time[TM_DATETIME_BUFFER_SIZE];
+  tm_format_time(time, &config->tf_base, current_time());
+  struct cbor_writer *w = cbor_init(lp_new(proto_pool), 1000);
+  cbor_open_block_with_length(w, 3);
+  cbor_string_string(w, "BIRD", BIRD_VERSION);
+  cbor_add_string(w, "body");
+  cbor_open_block(w);
+  cbor_add_string(w, "router_id");
+  cbor_add_int(w, config->router_id);
+  cbor_string_string(w, "hostname", config->hostname);
+  cbor_string_string(w, "server_time", time);
+  tm_format_time(time, &config->tf_base, boot_time);
+  cbor_string_string(w, "last_reboot", time);
+  tm_format_time(time, &config->tf_base, config->load_time);
+  cbor_string_string(w, "last_reconfiguration", 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
@@ -127,6 +156,40 @@ cmd_show_memory(void)
 #endif
   print_size("Total:", total);
   cli_msg(0, "");
+  
+  
+  struct cbor_writer *w = cbor_init(lp_new(proto_pool), 1000);
+  cbor_open_block_with_length(w, 2);
+
+  cbor_string_string(w, "BIRD memory usage", "header");
+
+  cbor_add_string(w, "body");
+  cbor_open_block(w);
+
+  struct resmem memory = rmemsize(rt_table_pool);
+  cbor_named_block_two_ints(w, "routing_tables", "effective", memory.effective, "overhead", memory.overhead);
+
+  memory = rmemsize(rta_pool);
+  cbor_named_block_two_ints(w, "route_attributes", "effective", memory.effective, "overhead", memory.overhead);
+
+  memory = rmemsize(proto_pool);
+  cbor_named_block_two_ints(w, "protocols", "effective", memory.effective, "overhead", memory.overhead);
+
+  memory = rmemsize(config_pool);
+  cbor_named_block_two_ints(w, "current_config", "effective", memory.effective, "overhead", memory.overhead);
+
+  memory = rmemsize(&root_pool);
+#ifdef HAVE_MMAP
+  cbor_named_block_two_ints(w, "standby", "effective", 0, "overhead", page_size * *pages_kept);
+#endif
+  memory.overhead += page_size * *pages_kept;
+  cbor_named_block_two_ints(w, "total", "effective", memory.effective, "overhead", memory.overhead);
+
+  cbor_close_block_or_list(w); // we do not know for sure, that standby memory will be printed, so we do not know number of block items. If we know that, we open the block for 6 (or 5) items and we do not close anything 
+
+
+  cbor_write_to_file(w, "/home/kkubecova/Dokumenty/bird/yang/show_memory_generated.yang");
+
 }
 
 void
index a3573effcb233a20b4d4abf0ed9504cc75069328..2e4ea86e2bacf41324590877cd242762aae9d8d7 100644 (file)
@@ -7,11 +7,22 @@ module show_status {
   description "cli show status format";
 
   typedef date-and-time {
-  type string {
-    pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+    type string {
+      pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
           + '(Z|[\+\-]\d{2}:\d{2})';
+    }
+  }
+
+  grouping timer {
+    leaf remains {
+      type decimal64 {
+        fraction-digits 3;
+      }
+    }
+    leaf count_time {
+      type uint32;
+    }
   }
-}
 
 
   container message {
@@ -39,6 +50,14 @@ module show_status {
       leaf last_reconfiguration {
         type date-and-time;
       }
+      container gr_restart {
+        leaf waiting_for_n_channels_to_recover {
+          type int32;
+        }
+        container wait_timer {
+          uses timer
+        }
+      }
     }
     leaf state {
       type string;