strcpy(x, "<error>");
}
+btime
+tm_get_real_time(btime t)
+{
+ btime dt = current_time() - t;
+ btime rt = current_real_time() - dt;
+ return rt;
+}
+
/* Replace %f in format string with usec scaled to requested precision */
static int
strfusec(char *buf, int size, const char *fmt, uint usec)
btime tm_parse_time(const char *x);
void tm_format_time(char *x, struct timeformat *fmt, btime t);
+btime tm_get_real_time(btime t);
int tm_format_real_time(char *x, size_t max, const char *fmt, btime t);
#endif
struct linpool *lp;
};
-void write_item(struct cbor_writer *writer, int8_t major, int num);
+void write_item(struct cbor_writer *writer, int8_t major, u64 num);
void check_memory(struct cbor_writer *writer, int add_size);
}
-void cbor_add_int(struct cbor_writer *writer, int item)
+void cbor_add_int(struct cbor_writer *writer, int64_t item)
{
if (item >= 0)
{
}
else
{
- write_item(writer, 1, item);
+ write_item(writer, 1, -item);
}
}
+void cbor_add_uint(struct cbor_writer *writer, u64 item)
+{
+ write_item(writer, 0, item);
+}
+
void cbor_add_tag(struct cbor_writer *writer, int item)
{
write_item(writer, 6, item);
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, u64 num)
{
major = major<<5;
check_memory(writer, 10);
+ log("writing %li %lx max for lower %lx ", num, num, ((u64)1<<(4*8))-1);
+ if (num > ((u64)1<<(4*8))-1)
+ { // We need 8 bytes to encode the num
+ log("loong num");
+ major += 0x1b; // reserving those bytes
+ writer->cbor[writer->pt] = major;
+ writer->pt++;
+ for (int i = 7; i>=0; i--)
+ { // write n-th byte of num
+ uint8_t to_write = (num>>(i*8)) & 0xff;
+ log("%x", to_write);
+ writer->cbor[writer->pt] = to_write;
+ writer->pt++;
+ }
+ return;
+ }
if (num > (1<<(2*8))-1)
{ // We need 4 bytes to encode the num
major += 0x1a; // reserving those bytes
for (int i = 3; i>=0; i--)
{ // write n-th byte of num
uint8_t to_write = (num>>(i*8)) & 0xff;
+ log("%x", to_write);
writer->cbor[writer->pt] = to_write;
writer->pt++;
}
return 1;
}
+int64_t preprocess_time(btime t) {
+ return tm_get_real_time(t) TO_S ;
+}
extern pool *rt_table_pool;
extern pool *rta_pool;
uint
cmd_show_status_cbor(byte *tbuf, uint capacity, struct linpool *lp)
{
+ log("show status");
struct cbor_writer *w = cbor_init(tbuf, capacity, lp);
cbor_open_block_with_length(w, 1);
cbor_add_string(w, "show_status:message");
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);
+ cbor_string_int(w, "server_time", preprocess_time(current_time()));
+ cbor_string_int(w, "last_reboot", preprocess_time(boot_time));
+ cbor_string_int(w, "last_reconfiguration", preprocess_time(config->load_time));
if (is_gr_active())
{
+ log("graceful restart");
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());
else
cbor_add_string(w, "Daemon is up and running");
cbor_write_to_file(w, "test.cbor");
+ log("leaving show status");
return w->pt;
}
{
if (compare_str(args->args[args->pt - 1].arg, args->args[args->pt - 1].len, sym->name))
{
- cbor_string_string(w, "name", args->args[args->pt - 1].arg);
+ cbor_add_string(w, "name");
+ cbor_nonterminated_string(w, args->args[args->pt - 1].arg, args->args[args->pt - 1].len);
cbor_string_string(w, "type", cf_symbol_class_name(sym));
return w->pt;
}
}
HASH_WALK_END;
}
- cbor_string_string(w, "name", args->args[args->pt - 1].arg);
+ cbor_add_string(w, "name");
+ cbor_nonterminated_string(w, args->args[args->pt - 1].arg, args->args[args->pt - 1].len);
cbor_string_string(w, "type", "symbol not known");
return w->pt;
}
struct value {
int major;
- int val;
+ int64_t val;
};
struct buff_reader {
struct value val;
byte *buff = reader->buff;
val.major = buff[reader->pt]>>5;
- log("in get value");
+ log("in get value are zou here?");
+ log("major is %x", val.major);
int first_byte_val = buff[reader->pt] - (val.major<<5);
if (first_byte_val <=23) {
val.val = first_byte_val;
{
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 == 0x1b)
+ {
+ for(int i = 1; i<=8; i++) {
+ val.val += buff[reader->pt+i]>>(64-(i*8));
+ }
+ reader->pt+=9;
} else if (first_byte_val == 0xff)
{
val.val = -1;
cbor_add_string(writer, value);
}
-void cbor_string_int(struct cbor_writer *writer, char *key, int value) {
+void cbor_string_int(struct cbor_writer *writer, char *key, int64_t value) {
cbor_add_string(writer, key);
cbor_add_int(writer, value);
}
+void cbor_string_uint(struct cbor_writer *writer, char *key, u64 value) {
+ cbor_add_string(writer, key);
+ cbor_add_uint(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);
cli_msg(-1000, "BIRD " BIRD_VERSION);
tm_format_time(tim, &config->tf_base, current_time());
- cli_msg(-1011, "Router ID is %R %i %x", config->router_id, config->router_id, config->router_id);
+ cli_msg(-1011, "Router ID is %R", 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);
cbor_add_string(w, "network");
cbor_open_list(w);
lsa_walk_rt_init(p, he, &rtl);
+ int dummy_id = 0;
while (lsa_walk_rt(&rtl))
{
if (rtl.type == LSART_NET)
struct ospf_lsa_header *net_lsa = &(net_he->lsa);
struct ospf_lsa_net *net_ln = net_he->lsa_body;
- cbor_open_block_with_length(w, 3);
+ cbor_open_block_with_length(w, 4);
+ cbor_string_int(w, "dummy_yang_id", dummy_id);
cbor_string_int(w, "network", net_lsa->id & net_ln->optx);
cbor_string_int(w, "len", u32_masklen(net_ln->optx));
cbor_string_int(w, "metric", rtl.metric);
}
else
{
- cbor_open_block_with_length(w, 2);
+ cbor_open_block_with_length(w, 3);
+ cbor_string_int(w, "dummy_yang_id", dummy_id);
cbor_string_int(w, "network", rtl.id);
cbor_string_int(w, "metric", rtl.metric);
}
}
else
{
- cbor_open_block_with_length(w, 3);
+ cbor_open_block_with_length(w, 4);
+ cbor_string_int(w, "dummy_yang_id", dummy_id);
cbor_string_int(w, "network", rtl.id);
cbor_string_int(w, "nif", rtl.nif);
cbor_string_int(w, "metric", rtl.metric);
}
}
+ dummy_id++;
}
cbor_close_block_or_list(w);
cbor_add_string(w, "routers");
cbor_open_list(w);
for (i = 0; i < lsa_net_count(lsa); i++)
+ {
+ cbor_open_block_with_length(w, 1);
cbor_string_int(w, "router", ln->routers[i]);
+ }
cbor_close_block_or_list(w);
}
if(rt.ebit)
{
- cbor_string_int(w, "lsa_type", 2);
+ cbor_string_int(w, "lsa_type_num", 2);
}
cbor_string_int(w, "metric", rt.metric);
cbor_close_block_or_list(w);
buf = px->rest;
- cbor_add_string(w, "prexixes");
+ cbor_add_string(w, "prefixes");
cbor_open_list(w);
char str[IPA_MAX_TEXT_LENGTH + 8] = "";
for (i = 0; i < px->pxcount; i++)
for (i = 0; i < j1; i++)
{
cbor_open_block(w);
+ cbor_string_int(w, "dummy_yang_id", i);
he = hea[i];
/* If there is no opened node, we open the LSA (if appropriate) or skip to the next one */
/* If it is still marked, we show it now. */
if (he->domain)
{
- cbor_add_string(w, "asbr");
cbor_open_block(w);
he->domain = 0;
--- /dev/null
+import cbor
+import json
+import sys
+import os
+import socket, struct
+import datetime
+
+
+class Command:
+ num = -1
+ def addr_to_str(self, addr):
+ return socket.inet_ntoa(struct.pack('!L', addr))
+
+ def print_answer(self, answer):
+ print(answer)
+
+class Memory(Command):
+ num = 1
+ def nums_to_str(self, answer, key):
+
+ e = answer["show_memory:message"]["body"][key]["effective"]
+ o = answer["show_memory:message"]["body"][key]["overhead"]
+ j_e = " B"
+ j_o = " B"
+ if e > 9999:
+ e = e/1000
+ j_e = "kB"
+ if o > 9999:
+ o = o/1000
+ j_o = "kB"
+ return f"{e:>7} {j_e} {o:>7} {j_o}"
+
+ def print_answer(self, answer):
+ print()
+ print("BIRD memory usage")
+ keys = answer["show_memory:message"]["body"].keys()
+ first_column_width = len("route attributes ")
+ print(" " * (first_column_width+4), "Effective ", "Overhead")
+ for key in keys:
+ name = key.replace("_", " ")
+ print(name,":", " "*(first_column_width - len(name)), self.nums_to_str(answer, key))
+
+
+class Status(Command):
+ num = 0
+
+ def print_answer(self, answer):
+ print(answer)
+ print()
+ print("BIRD", answer["show_status:message"]["version"])
+ for key in answer["show_status:message"]["body"].keys():
+ name = key.replace("_", " ")
+ if key == "router_id":
+ print(name, self.addr_to_str( answer["show_status:message"]["body"][key]))
+ elif key in "server_time last_reboot last_reconfiguration":
+ print(name, datetime.datetime.fromtimestamp(answer["show_status:message"]["body"][key]))
+ else:
+ print(name, answer["show_status:message"]["body"][key])
+ print(answer["show_status:message"]["state"])
+
+
+class Symbols(Command):
+ num = 2
+
+ def print_answer(self, answer):
+ print()
+ for item in answer["show_symbols:message"]["table"]:
+ print(f"{item['name']:<15} {item['type']}")
+
+
+class Ospf(Command):
+ num = 3
+
+ def print_lsa_router(self, area):
+ print ("\trouter", self.addr_to_str(area['router']))
+ print("\t\tdistance", area['distance'])
+ if ('vlink' in area.keys()):
+ for vlink in area['vlink']:
+ print(f"\t\tvlink {self.addr_to_str( vlink['vlink'])} metric {vlink['metric']}")
+ if ('router_metric' in area.keys()):
+ for router in area['router_metric']:
+ print(f"\t\trouter {self.addr_to_str( router['router'])} metric {router['metric']}")
+ for network in area['network']:
+ addr = self.addr_to_str(network['network'])
+ if('nif' in network):
+ print(f"\t\tnetwork [{addr}-{network['nif']}] metric {network['metric']}")
+ elif('len' in area.keys()):
+ print(f"\t\tnetwork {addr}/{network['len']} metric {network['metric']}")
+ else:
+ print(f"\t\tnetwork [{addr}] metric {network['metric']}")
+ if ('stubnet' in area.keys()):
+ for stubnet in area['stubnet']:
+ print(f"\t\tstubnet {self.addr_to_str(stubnet['stubnet'])}/{stubnet['len']} metric {stubnet['metric']}")
+
+ def print_lsa_network(self, area):
+ if ('ospf2' in area.keys()):
+ print(f"\tnetwork {self.addr_to_str(area['ospf2']['network'])}/{area['ospf2']['optx']}")
+ print(f"\t\tdr {self.addr_to_str(area['ospf2']['dr'])}")
+ elif ('ospf' in area.keys()):
+ print(f"\tnetwork [{self.addr_to_str(area['ospf']['network'])}-{area['ospf']['lsa_id']}]")
+ print("\t\tdistance", area['distance'])
+ for router in area['routers']:
+ print(f"\t\trouter {self.addr_to_str(router['router'])}")
+
+ def print_lsa_sum_net(self, area):
+ print(f"\t\txnetwork {area['net']} metric {area['metric']}")
+
+ def print_lsa_sum_rt(self, area):
+ print(f"\t\txrouter {self.addr_to_str(area['router'])} metric {area['metric']}")
+
+ def print_lsa_external(self, area):
+ if('lsa_type_num' in area.keys()):
+ print(f"\t\t{area['lsa_type']} {self.addr_to_str(area['rt_net'])} metric{area[lsa_type_num]} {area['metric']}%s%s")
+ else:
+ print(f"\t\t{area['lsa_type']} {self.addr_to_str(area['rt_net'])} metric {area['metric']}{area['via']}{area['tag']}")
+
+ def print_lsa_prefix(self, area):
+ for prefix in area['prefixes']:
+ if 'metric' in prefix.keys():
+ print(f"\t\tstubnet {self.addr_to_str(prefix['stubnet'])} metric {prefix['metric']}")
+
+ def print_answer(self, answer):
+ print()
+ if ("error" in answer["show_ospf:message"].keys()):
+ print("error: ", answer["show_ospf:message"]["error"])
+ return
+ if ("not implemented" in answer["show_ospf:message"].keys()):
+ print("not implemented: ", answer["show_ospf:message"]["not implemented"])
+ return
+ for area in answer["show_ospf:message"]["areas"]:
+ if 'area' in area.keys():
+ print ("area", self.addr_to_str(area['area']))
+ print()
+ if 'lsa_router' in area.keys():
+ self.print_lsa_router(area['lsa_router'])
+ elif 'lsa_network' in area.keys():
+ self.print_lsa_network(area['lsa_network'])
+ elif 'lsa_sum_net' in area.keys():
+ self.print_lsa_sum_net(area['lsa_sum_net'])
+ elif 'lsa_sum_rt' in area.keys():
+ self.print_lsa_sum_rt(area['lsa_sum_rt'])
+ elif 'lsa_external' in area.keys():
+ self.print_lsa_external(area['lsa_external'])
+ elif 'lsa_prefix' in area.keys():
+ self.print_lsa_prefix(area['lsa_prefix'])
+ if('asbrs' in area.keys()):
+ for asbr in area['asbrs']:
+ if('other_ABSRs' in asbr.keys()):
+ print("other ASBRs")
+ print("other ASBRs")
+ print(f"\trouter {self.addr_to_str(asbr['router'])}")
+
+command_dictionary = {"status":0, "memory":1, "symbols":2, "ospf":3}
+
+def get_command_class(string):
+ if string == "status":
+ return Status()
+ if string == "memory":
+ return Memory()
+ if string == "symbols":
+ return Symbols()
+ if string == "ospf":
+ return Ospf()
+ raise Exception(f"Command {string} not known. Expected status, memory, symbols or ospf")
+
+def run_on_machine(dev, cmd):
+ ws = os.system(f"ip netns exec {dev} {cmd}")
+ if os.WIFEXITED(ws):
+ ec = os.WEXITSTATUS(ws)
+ else:
+ ec = False
+
+ if ec != 0:
+ raise Exception(f"Command {cmd} exited with exit code {ws}")
+
+
+arguments = sys.argv
+if (len(sys.argv) <= 2):
+ raise Exception("Expected command, no argunents given.")
+if (len(sys.argv) == 3):
+ raise Exception(f"only one ({sys.argv[2]}) command given, that is not implemented")
+if(sys.argv[2] != "show"):
+ raise Exception(f"Expected 'dev show status/memory/symbols/ospf', unknown {sys.argv[2]}.")
+comm = get_command_class(sys.argv[3])
+
+command = {"command:do":{"command":comm.num, "args":[]}}
+for i in range (4, len(sys.argv)):
+ command["command:do"]["args"].append({"arg": sys.argv[i]})
+print(command)
+
+with open(os.getcwd()+"/command.cbor", "wb") as of:
+ cbor.dump(command, of)
+
+run_on_machine(sys.argv[1], f"cat command.cbor | sudo socat UNIX-CONNECT:{os.getcwd()}/bird-yang.ctl STDIO > answer.cbor")
+
+
+with open("answer.cbor", "br") as cbor_file:
+ answer = cbor.load(cbor_file)
+
+ comm.print_answer(answer)
-¡jcommand:do¢gcommand\ 3dargs\82¡carghtopology¡cargeospf6
\ No newline at end of file
+¡jcommand:do¢gcommand\ 1dargs\84¡cargculg¡cargbui¡cargb76¡cargbkl
\ No newline at end of file
-{"command:do":{"command": 3, "args":[{"arg":"topology"}, {"arg":"ospf6"}]}}
+{"command:do":{"command": 3, "args":[{"arg":"topology"}, {"arg":"ospf4"}]}}
leaf vlink {
type int32;
}
- leaf metric {
- type int32;
- }
+ uses metric;
}
list router_metric {
}
list network {
- key "network";
+ key "dummy_yang_id";
+ leaf dummy_yang_id {
+ type int32;
+ }
leaf network {
type int32;
}
leaf rt_net {
type string;
}
- leaf lsa_type {
+ leaf lsa_type_num {
type int32;
}
uses metric;
grouping lsa_prefix {
container lsa_prefix {
list prefixes {
+ key "stubnet";
leaf stubnet {
- type string;
+ type int32;
}
uses metric;
}
}
}
- container ospf {
+ container message {
leaf error {
mandatory false;
type string;
}
list areas {
+ key "dummy_yang_id";
+ leaf dummy_yang_id {
+ type int32;
+ }
leaf area {
type int32;
}
}
}
list asbrs {
- container asbr {
- leaf other_ABSRs {
- type none;
- }
- uses router;
- uses lsa_external;
+ key "router";
+
+ leaf other_ABSRs {
+ type empty;
}
+ uses router;
+ uses lsa_external;
+
}
}
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
type string;
}
leaf server_time {
- type int32;
+ type int64;
}
leaf last_reboot {
- type int32;
+ type int64;
}
leaf last_reconfiguration {
- type int32;
+ type int64;
}
container gr_restart {
leaf waiting_for_n_channels_to_recover {
"revision": "",
"conformance-type": "implement"
},
+ {
+ "name": "show_ospf",
+ "namespace": "https://bird.nic.cz/yang/v2.15/cli-debug",
+ "revision": "",
+ "conformance-type": "implement"
+ },
{
"name": "show_protocols",
"namespace": "https://bird.nic.cz/yang/v2.15/cli-debug",