mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 01:31:55 +00:00
CLI: Dumping internal data structures to files, not to debug output
All the 'dump something' CLI commands now have a new mandatory argument -- name of the file where to dump the data. This allows for more flexible dumping even for production deployments where the debug output is by default off. Also the dump commands are now restricted (they weren't before) to assure that only the appropriate users can run these time consuming commands.
This commit is contained in:
parent
4dd5b3d90e
commit
da8a23277e
@ -1454,8 +1454,12 @@ This argument can be omitted if there exists only a single instance.
|
|||||||
<tag><label id="cli-debug">debug <m/protocol/|<m/pattern/|all all|off|{ states|routes|filters|events|packets [, <m/.../] }</tag>
|
<tag><label id="cli-debug">debug <m/protocol/|<m/pattern/|all all|off|{ states|routes|filters|events|packets [, <m/.../] }</tag>
|
||||||
Control protocol debugging.
|
Control protocol debugging.
|
||||||
|
|
||||||
<tag><label id="cli-dump">dump resources|sockets|interfaces|neighbors|attributes|routes|protocols</tag>
|
<tag><label id="cli-dump">dump resources|sockets|interfaces|neighbors|attributes|routes|protocols "<m/file/"</tag>
|
||||||
Dump contents of internal data structures to the debugging output.
|
Truncates the given file and dumps contents of internal data structures
|
||||||
|
there. By sending SIGUSR1, you get all of these concatenated to
|
||||||
|
<cf/bird.dump/ in the current directory. The file is only readable for
|
||||||
|
the user running the daemon. The format of dump files is internal and
|
||||||
|
could change in the future.
|
||||||
|
|
||||||
<tag><label id="cli-echo">echo all|off|{ <m/list of log classes/ } [ <m/buffer-size/ ]</tag>
|
<tag><label id="cli-echo">echo all|off|{ <m/list of log classes/ } [ <m/buffer-size/ ]</tag>
|
||||||
Control echoing of log messages to the command-line output.
|
Control echoing of log messages to the command-line output.
|
||||||
|
@ -72,6 +72,7 @@ Reply codes of BIRD command-line interface
|
|||||||
8006 Reload failed
|
8006 Reload failed
|
||||||
8007 Access denied
|
8007 Access denied
|
||||||
8008 Evaluation runtime error
|
8008 Evaluation runtime error
|
||||||
|
8009 Failed to open file
|
||||||
|
|
||||||
9000 Command too long
|
9000 Command too long
|
||||||
9001 Parse error
|
9001 Parse error
|
||||||
|
@ -97,7 +97,7 @@ if ($3) return 0;
|
|||||||
]])
|
]])
|
||||||
m4_ifelse($4,,,[[
|
m4_ifelse($4,,,[[
|
||||||
FID_DUMP_BODY()m4_dnl
|
FID_DUMP_BODY()m4_dnl
|
||||||
debug("%s" $4 "\n", INDENT, $5);
|
RDUMP("%s" $4 "\n", INDENT, $5);
|
||||||
]])
|
]])
|
||||||
FID_INTERPRET_EXEC()m4_dnl
|
FID_INTERPRET_EXEC()m4_dnl
|
||||||
const $1 $2 = whati->$2
|
const $1 $2 = whati->$2
|
||||||
@ -168,7 +168,7 @@ FID_LINEARIZE_BODY()m4_dnl
|
|||||||
pos = linearize(dest, whati->fvar, pos);
|
pos = linearize(dest, whati->fvar, pos);
|
||||||
item->varcount = whati->varcount;
|
item->varcount = whati->varcount;
|
||||||
FID_DUMP_BODY()m4_dnl
|
FID_DUMP_BODY()m4_dnl
|
||||||
debug("%snumber of varargs %u\n", INDENT, item->varcount);
|
RDUMP("%snumber of varargs %u\n", INDENT, item->varcount);
|
||||||
FID_SAME_BODY()m4_dnl
|
FID_SAME_BODY()m4_dnl
|
||||||
if (f1->varcount != f2->varcount) return 0;
|
if (f1->varcount != f2->varcount) return 0;
|
||||||
FID_INTERPRET_BODY()
|
FID_INTERPRET_BODY()
|
||||||
@ -240,7 +240,7 @@ FID_NEW_METHOD()m4_dnl
|
|||||||
args = NULL; /* The rest is the line itself */
|
args = NULL; /* The rest is the line itself */
|
||||||
FID_METHOD_CALL() , arg$1
|
FID_METHOD_CALL() , arg$1
|
||||||
FID_DUMP_BODY()m4_dnl
|
FID_DUMP_BODY()m4_dnl
|
||||||
f_dump_line(item->fl$1, indent + 1);
|
f_dump_line(dreq, item->fl$1, indent + 1);
|
||||||
FID_LINEARIZE_BODY()m4_dnl
|
FID_LINEARIZE_BODY()m4_dnl
|
||||||
item->fl$1 = f_linearize(whati->f$1, $2);
|
item->fl$1 = f_linearize(whati->f$1, $2);
|
||||||
FID_SAME_BODY()m4_dnl
|
FID_SAME_BODY()m4_dnl
|
||||||
@ -433,13 +433,13 @@ m4_undivert(113)
|
|||||||
|
|
||||||
]])m4_dnl
|
]])m4_dnl
|
||||||
|
|
||||||
FID_DUMP_CALLER()m4_dnl Case in another big switch used in instruction dumping (debug)
|
FID_DUMP_CALLER()m4_dnl Case in another big switch used in instruction dumping
|
||||||
case INST_NAME(): f_dump_line_item_]]INST_NAME()[[(item, indent + 1); break;
|
case INST_NAME(): f_dump_line_item_]]INST_NAME()[[(dreq, item, indent + 1); break;
|
||||||
|
|
||||||
FID_DUMP()m4_dnl The dumper itself
|
FID_DUMP()m4_dnl The dumper itself
|
||||||
m4_ifdef([[FID_DUMP_BODY_EXISTS]],
|
m4_ifdef([[FID_DUMP_BODY_EXISTS]],
|
||||||
[[static inline void f_dump_line_item_]]INST_NAME()[[(const struct f_line_item *item_, const int indent)]],
|
[[static inline void f_dump_line_item_]]INST_NAME()[[(struct dump_request *dreq, const struct f_line_item *item_, const int indent)]],
|
||||||
[[static inline void f_dump_line_item_]]INST_NAME()[[(const struct f_line_item *item UNUSED, const int indent UNUSED)]])
|
[[static inline void f_dump_line_item_]]INST_NAME()[[(struct dump_request *dreq UNUSED, const struct f_line_item *item UNUSED, const int indent UNUSED)]])
|
||||||
m4_undefine([[FID_DUMP_BODY_EXISTS]])
|
m4_undefine([[FID_DUMP_BODY_EXISTS]])
|
||||||
{
|
{
|
||||||
#define item (&(item_->i_]]INST_NAME()[[))
|
#define item (&(item_->i_]]INST_NAME()[[))
|
||||||
@ -676,22 +676,22 @@ static const char f_dump_line_indent_str[] = " ";
|
|||||||
|
|
||||||
FID_WR_PUT(6)
|
FID_WR_PUT(6)
|
||||||
|
|
||||||
void f_dump_line(const struct f_line *dest, uint indent)
|
void f_dump_line(struct dump_request *dreq, const struct f_line *dest, uint indent)
|
||||||
{
|
{
|
||||||
if (!dest) {
|
if (!dest) {
|
||||||
debug("%sNo filter line (NULL)\n", INDENT);
|
RDUMP("%sNo filter line (NULL)\n", INDENT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
debug("%sFilter line %p (len=%u)\n", INDENT, dest, dest->len);
|
RDUMP("%sFilter line %p (len=%u)\n", INDENT, dest, dest->len);
|
||||||
for (uint i=0; i<dest->len; i++) {
|
for (uint i=0; i<dest->len; i++) {
|
||||||
const struct f_line_item *item = &dest->items[i];
|
const struct f_line_item *item = &dest->items[i];
|
||||||
debug("%sInstruction %s at line %u\n", INDENT, f_instruction_name_(item->fi_code), item->lineno);
|
RDUMP("%sInstruction %s at line %u\n", INDENT, f_instruction_name_(item->fi_code), item->lineno);
|
||||||
switch (item->fi_code) {
|
switch (item->fi_code) {
|
||||||
FID_WR_PUT(7)
|
FID_WR_PUT(7)
|
||||||
default: bug("Unknown instruction %x in f_dump_line", item->fi_code);
|
default: bug("Unknown instruction %x in f_dump_line", item->fi_code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug("%sFilter line %p dump done\n", INDENT, dest);
|
RDUMP("%sFilter line %p dump done\n", INDENT, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Linearize */
|
/* Linearize */
|
||||||
@ -721,10 +721,6 @@ f_linearize_concat(const struct f_inst * const inst[], uint count, uint results)
|
|||||||
out->len = linearize(out, inst[i], out->len);
|
out->len = linearize(out, inst[i], out->len);
|
||||||
|
|
||||||
out->results = results;
|
out->results = results;
|
||||||
|
|
||||||
#ifdef LOCAL_DEBUG
|
|
||||||
f_dump_line(out, 0);
|
|
||||||
#endif
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,11 +182,11 @@
|
|||||||
* m4_dnl This structure is returned from the linearizer (105).
|
* m4_dnl This structure is returned from the linearizer (105).
|
||||||
* m4_dnl For writing directly to this structure, use FID_LINE_IN.
|
* m4_dnl For writing directly to this structure, use FID_LINE_IN.
|
||||||
*
|
*
|
||||||
* m4_dnl f_dump_line_item_FI_EXAMPLE(const struct f_line_item *item, const int indent)
|
* m4_dnl f_dump_line_item_FI_EXAMPLE(struct dump_request *dreq, const struct f_line_item *item, const int indent)
|
||||||
* m4_dnl {
|
* m4_dnl {
|
||||||
* m4_dnl (104) [[ put it here ]]
|
* m4_dnl (104) [[ put it here ]]
|
||||||
* m4_dnl }
|
* m4_dnl }
|
||||||
* m4_dnl This code dumps the instruction on debug. Note that the argument
|
* m4_dnl This code dumps the instruction via RDUMP. Note that the argument
|
||||||
* m4_dnl is the linearized instruction; if the instruction has arguments,
|
* m4_dnl is the linearized instruction; if the instruction has arguments,
|
||||||
* m4_dnl their code has already been linearized and their value is taken
|
* m4_dnl their code has already been linearized and their value is taken
|
||||||
* m4_dnl from the value stack.
|
* m4_dnl from the value stack.
|
||||||
|
@ -68,7 +68,7 @@ struct f_line *f_linearize_concat(const struct f_inst * const inst[], uint count
|
|||||||
static inline struct f_line *f_linearize(const struct f_inst *root, uint results)
|
static inline struct f_line *f_linearize(const struct f_inst *root, uint results)
|
||||||
{ return f_linearize_concat(&root, 1, results); }
|
{ return f_linearize_concat(&root, 1, results); }
|
||||||
|
|
||||||
void f_dump_line(const struct f_line *, uint indent);
|
void f_dump_line(struct dump_request *, const struct f_line *, uint indent);
|
||||||
|
|
||||||
|
|
||||||
/* Recursive iteration over filter instructions */
|
/* Recursive iteration over filter instructions */
|
||||||
|
@ -251,10 +251,10 @@ ca_free(resource *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ca_dump(resource *r)
|
ca_dump(struct dump_request *dreq, resource *r)
|
||||||
{
|
{
|
||||||
struct custom_attribute *ca = (void *) r;
|
struct custom_attribute *ca = (void *) r;
|
||||||
debug("name \"%s\" id 0x%04x ea_type 0x%02x f_type 0x%02x\n",
|
RDUMP("name \"%s\" id 0x%04x ea_type 0x%02x f_type 0x%02x\n",
|
||||||
ca->name, ca->fda->ea_code, ca->fda->type, ca->fda->f_type);
|
ca->name, ca->fda->ea_code, ca->fda->type, ca->fda->f_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,11 +181,6 @@ interpret(struct filter_state *fs, const struct f_line *line, uint argc, const s
|
|||||||
#define curline fstk->estk[fstk->ecnt-1]
|
#define curline fstk->estk[fstk->ecnt-1]
|
||||||
#define prevline fstk->estk[fstk->ecnt-2]
|
#define prevline fstk->estk[fstk->ecnt-2]
|
||||||
|
|
||||||
#ifdef LOCAL_DEBUG
|
|
||||||
debug("Interpreting line.");
|
|
||||||
f_dump_line(line, 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (fstk->ecnt > 0) {
|
while (fstk->ecnt > 0) {
|
||||||
while (curline.pos < curline.line->len) {
|
while (curline.pos < curline.line->len) {
|
||||||
const struct f_line_item *what = &(curline.line->items[curline.pos++]);
|
const struct f_line_item *what = &(curline.line->items[curline.pos++]);
|
||||||
@ -474,37 +469,37 @@ filter_commit(struct config *new, struct config *old)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void filters_dump_all(void)
|
void filters_dump_all(struct dump_request *dreq)
|
||||||
{
|
{
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
WALK_LIST(sym, config->symbols) {
|
WALK_LIST(sym, config->symbols) {
|
||||||
switch (sym->class) {
|
switch (sym->class) {
|
||||||
case SYM_FILTER:
|
case SYM_FILTER:
|
||||||
debug("Named filter %s:\n", sym->name);
|
RDUMP("Named filter %s:\n", sym->name);
|
||||||
f_dump_line(sym->filter->root, 1);
|
f_dump_line(dreq, sym->filter->root, 1);
|
||||||
break;
|
break;
|
||||||
case SYM_FUNCTION:
|
case SYM_FUNCTION:
|
||||||
debug("Function %s:\n", sym->name);
|
RDUMP("Function %s:\n", sym->name);
|
||||||
f_dump_line(sym->function, 1);
|
f_dump_line(dreq, sym->function, 1);
|
||||||
break;
|
break;
|
||||||
case SYM_PROTO:
|
case SYM_PROTO:
|
||||||
{
|
{
|
||||||
debug("Protocol %s:\n", sym->name);
|
RDUMP("Protocol %s:\n", sym->name);
|
||||||
struct channel *c;
|
struct channel *c;
|
||||||
WALK_LIST(c, sym->proto->proto->channels) {
|
WALK_LIST(c, sym->proto->proto->channels) {
|
||||||
debug(" Channel %s (%s) IMPORT", c->name, net_label[c->net_type]);
|
RDUMP(" Channel %s (%s) IMPORT", c->name, net_label[c->net_type]);
|
||||||
if (c->in_filter == FILTER_ACCEPT)
|
if (c->in_filter == FILTER_ACCEPT)
|
||||||
debug(" ALL\n");
|
RDUMP(" ALL\n");
|
||||||
else if (c->in_filter == FILTER_REJECT)
|
else if (c->in_filter == FILTER_REJECT)
|
||||||
debug(" NONE\n");
|
RDUMP(" NONE\n");
|
||||||
else if (c->in_filter == FILTER_UNDEF)
|
else if (c->in_filter == FILTER_UNDEF)
|
||||||
debug(" UNDEF\n");
|
RDUMP(" UNDEF\n");
|
||||||
else if (c->in_filter->sym) {
|
else if (c->in_filter->sym) {
|
||||||
ASSERT(c->in_filter->sym->filter == c->in_filter);
|
ASSERT(c->in_filter->sym->filter == c->in_filter);
|
||||||
debug(" named filter %s\n", c->in_filter->sym->name);
|
RDUMP(" named filter %s\n", c->in_filter->sym->name);
|
||||||
} else {
|
} else {
|
||||||
debug("\n");
|
RDUMP("\n");
|
||||||
f_dump_line(c->in_filter->root, 2);
|
f_dump_line(dreq, c->in_filter->root, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ int f_same(const struct f_line *f1, const struct f_line *f2);
|
|||||||
|
|
||||||
void filter_commit(struct config *new, struct config *old);
|
void filter_commit(struct config *new, struct config *old);
|
||||||
|
|
||||||
void filters_dump_all(void);
|
void filters_dump_all(struct dump_request *);
|
||||||
|
|
||||||
#define FILTER_ACCEPT NULL
|
#define FILTER_ACCEPT NULL
|
||||||
#define FILTER_REJECT ((struct filter *) 1)
|
#define FILTER_REJECT ((struct filter *) 1)
|
||||||
|
@ -242,4 +242,15 @@ static inline u64 u64_hash0(u64 v, u32 p, u64 acc)
|
|||||||
static inline u32 u64_hash(u64 v)
|
static inline u32 u64_hash(u64 v)
|
||||||
{ return hash_value(u64_hash0(v, HASH_PARAM, 0)); }
|
{ return hash_value(u64_hash0(v, HASH_PARAM, 0)); }
|
||||||
|
|
||||||
|
/* Dumping */
|
||||||
|
struct dump_request {
|
||||||
|
u64 size;
|
||||||
|
btime begin;
|
||||||
|
uint indent, offset;
|
||||||
|
void (*write)(struct dump_request *, const char *fmt, ...);
|
||||||
|
void (*report)(struct dump_request *, int state, const char *fmt, ...);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RDUMP(...) dreq->write(dreq, __VA_ARGS__)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -36,11 +36,11 @@ ev_postpone(event *e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ev_dump(resource *r)
|
ev_dump(struct dump_request *dreq, resource *r)
|
||||||
{
|
{
|
||||||
event *e = (event *) r;
|
event *e = (event *) r;
|
||||||
|
|
||||||
debug("(code %p, data %p, %s)\n",
|
RDUMP("(code %p, data %p, %s)\n",
|
||||||
e->hook,
|
e->hook,
|
||||||
e->data,
|
e->data,
|
||||||
e->n.next ? "scheduled" : "inactive");
|
e->n.next ? "scheduled" : "inactive");
|
||||||
|
@ -44,7 +44,7 @@ struct linpool {
|
|||||||
_Thread_local linpool *tmp_linpool;
|
_Thread_local linpool *tmp_linpool;
|
||||||
|
|
||||||
static void lp_free(resource *);
|
static void lp_free(resource *);
|
||||||
static void lp_dump(resource *);
|
static void lp_dump(struct dump_request *, resource *);
|
||||||
static resource *lp_lookup(resource *, unsigned long);
|
static resource *lp_lookup(resource *, unsigned long);
|
||||||
static struct resmem lp_memsize(resource *r);
|
static struct resmem lp_memsize(resource *r);
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ lp_free(resource *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lp_dump(resource *r)
|
lp_dump(struct dump_request *dreq, resource *r)
|
||||||
{
|
{
|
||||||
linpool *m = (linpool *) r;
|
linpool *m = (linpool *) r;
|
||||||
struct lp_chunk *c;
|
struct lp_chunk *c;
|
||||||
@ -281,7 +281,7 @@ lp_dump(resource *r)
|
|||||||
;
|
;
|
||||||
for(cntl=0, c=m->first_large; c; c=c->next, cntl++)
|
for(cntl=0, c=m->first_large; c; c=c->next, cntl++)
|
||||||
;
|
;
|
||||||
debug("(count=%d+%d total=%d+%d)\n",
|
RDUMP("(count=%d+%d total=%d+%d)\n",
|
||||||
cnt,
|
cnt,
|
||||||
cntl,
|
cntl,
|
||||||
m->total,
|
m->total,
|
||||||
|
@ -35,7 +35,7 @@ struct pool {
|
|||||||
const char *name;
|
const char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pool_dump(resource *);
|
static void pool_dump(struct dump_request *, resource *);
|
||||||
static void pool_free(resource *);
|
static void pool_free(resource *);
|
||||||
static resource *pool_lookup(resource *, unsigned long);
|
static resource *pool_lookup(resource *, unsigned long);
|
||||||
static struct resmem pool_memsize(resource *P);
|
static struct resmem pool_memsize(resource *P);
|
||||||
@ -51,8 +51,6 @@ static struct resclass pool_class = {
|
|||||||
|
|
||||||
pool root_pool;
|
pool root_pool;
|
||||||
|
|
||||||
static int indent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rp_new - create a resource pool
|
* rp_new - create a resource pool
|
||||||
* @p: parent pool
|
* @p: parent pool
|
||||||
@ -100,16 +98,16 @@ pool_free(resource *P)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pool_dump(resource *P)
|
pool_dump(struct dump_request *dreq, resource *P)
|
||||||
{
|
{
|
||||||
pool *p = (pool *) P;
|
pool *p = (pool *) P;
|
||||||
resource *r;
|
resource *r;
|
||||||
|
|
||||||
debug("%s\n", p->name);
|
RDUMP("%s\n", p->name);
|
||||||
indent += 3;
|
dreq->indent += 3;
|
||||||
WALK_LIST(r, p->inside)
|
WALK_LIST(r, p->inside)
|
||||||
rdump(r);
|
rdump(dreq, r);
|
||||||
indent -= 3;
|
dreq->indent -= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct resmem
|
static struct resmem
|
||||||
@ -199,20 +197,28 @@ rfree(void *res)
|
|||||||
* It works by calling a class-specific dump function.
|
* It works by calling a class-specific dump function.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
rdump(void *res)
|
rdump(struct dump_request *dreq, void *res)
|
||||||
{
|
{
|
||||||
char x[16];
|
char x[16];
|
||||||
resource *r = res;
|
resource *r = res;
|
||||||
|
|
||||||
bsprintf(x, "%%%ds%%p ", indent);
|
bsprintf(x, "%%%ds%%p ", dreq->indent);
|
||||||
debug(x, "", r);
|
RDUMP(x, "", r);
|
||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
debug("%s ", r->class->name);
|
RDUMP("%s ", r->class->name);
|
||||||
r->class->dump(r);
|
r->class->dump(dreq, r);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
debug("NULL\n");
|
RDUMP("NULL\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void page_dump(struct dump_request *req);
|
||||||
|
|
||||||
|
void resource_dump(struct dump_request *req)
|
||||||
|
{
|
||||||
|
rdump(req, &root_pool);
|
||||||
|
page_dump(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct resmem
|
struct resmem
|
||||||
@ -251,6 +257,7 @@ ralloc(pool *p, struct resclass *c)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* rlookup - look up a memory location
|
* rlookup - look up a memory location
|
||||||
* @a: memory address
|
* @a: memory address
|
||||||
@ -273,6 +280,7 @@ rlookup(unsigned long a)
|
|||||||
else
|
else
|
||||||
debug("Not found.\n");
|
debug("Not found.\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* resource_init - initialize the resource manager
|
* resource_init - initialize the resource manager
|
||||||
@ -316,11 +324,11 @@ static void mbl_free(resource *r UNUSED)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mbl_debug(resource *r)
|
static void mbl_debug(struct dump_request *dreq, resource *r)
|
||||||
{
|
{
|
||||||
struct mblock *m = (struct mblock *) r;
|
struct mblock *m = (struct mblock *) r;
|
||||||
|
|
||||||
debug("(size=%d)\n", m->size);
|
RDUMP("(size=%d)\n", m->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static resource *
|
static resource *
|
||||||
|
@ -30,7 +30,7 @@ struct resclass {
|
|||||||
char *name; /* Resource class name */
|
char *name; /* Resource class name */
|
||||||
unsigned size; /* Standard size of single resource */
|
unsigned size; /* Standard size of single resource */
|
||||||
void (*free)(resource *); /* Freeing function */
|
void (*free)(resource *); /* Freeing function */
|
||||||
void (*dump)(resource *); /* Dump to debug output */
|
void (*dump)(struct dump_request *, resource *); /* Dump to debug output */
|
||||||
resource *(*lookup)(resource *, unsigned long); /* Look up address (only for debugging) */
|
resource *(*lookup)(resource *, unsigned long); /* Look up address (only for debugging) */
|
||||||
struct resmem (*memsize)(resource *); /* Return size of memory used by the resource, may be NULL */
|
struct resmem (*memsize)(resource *); /* Return size of memory used by the resource, may be NULL */
|
||||||
};
|
};
|
||||||
@ -46,7 +46,10 @@ void resource_init(void);
|
|||||||
pool *rp_new(pool *, const char *); /* Create new pool */
|
pool *rp_new(pool *, const char *); /* Create new pool */
|
||||||
pool *rp_newf(pool *, const char *, ...); /* Create a new pool with a formatted string as its name */
|
pool *rp_newf(pool *, const char *, ...); /* Create a new pool with a formatted string as its name */
|
||||||
void rfree(void *); /* Free single resource */
|
void rfree(void *); /* Free single resource */
|
||||||
void rdump(void *); /* Dump to debug output */
|
|
||||||
|
struct dump_request;
|
||||||
|
void rdump(struct dump_request *, void *); /* Dump to debug output */
|
||||||
|
void resource_dump(struct dump_request *); /* Dump the root pool */
|
||||||
struct resmem rmemsize(void *res); /* Return size of memory used by the resource */
|
struct resmem rmemsize(void *res); /* Return size of memory used by the resource */
|
||||||
void rlookup(unsigned long); /* Look up address (only for debugging) */
|
void rlookup(unsigned long); /* Look up address (only for debugging) */
|
||||||
void rmove(void *, pool *); /* Move to a different pool */
|
void rmove(void *, pool *); /* Move to a different pool */
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void slab_free(resource *r);
|
static void slab_free(resource *r);
|
||||||
static void slab_dump(resource *r);
|
static void slab_dump(struct dump_request *dreq, resource *r);
|
||||||
static resource *slab_lookup(resource *r, unsigned long addr);
|
static resource *slab_lookup(resource *r, unsigned long addr);
|
||||||
static struct resmem slab_memsize(resource *r);
|
static struct resmem slab_memsize(resource *r);
|
||||||
|
|
||||||
@ -378,7 +378,7 @@ slab_free(resource *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
slab_dump(resource *r)
|
slab_dump(struct dump_request *dreq, resource *r)
|
||||||
{
|
{
|
||||||
slab *s = (slab *) r;
|
slab *s = (slab *) r;
|
||||||
int ec=0, pc=0, fc=0;
|
int ec=0, pc=0, fc=0;
|
||||||
@ -389,7 +389,7 @@ slab_dump(resource *r)
|
|||||||
pc++;
|
pc++;
|
||||||
WALK_TLIST(sl_head, h, &s->full_heads)
|
WALK_TLIST(sl_head, h, &s->full_heads)
|
||||||
fc++;
|
fc++;
|
||||||
debug("(%de+%dp+%df blocks per %d objs per %d bytes)\n", ec, pc, fc, s->objs_per_slab, s->obj_size);
|
RDUMP("(%de+%dp+%df blocks per %d objs per %d bytes)\n", ec, pc, fc, s->objs_per_slab, s->obj_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct resmem
|
static struct resmem
|
||||||
|
@ -92,7 +92,7 @@ void sk_reallocate(sock *); /* Free and allocate tbuf & rbuf */
|
|||||||
void sk_set_rbsize(sock *s, uint val); /* Resize RX buffer */
|
void sk_set_rbsize(sock *s, uint val); /* Resize RX buffer */
|
||||||
void sk_set_tbsize(sock *s, uint val); /* Resize TX buffer, keeping content */
|
void sk_set_tbsize(sock *s, uint val); /* Resize TX buffer, keeping content */
|
||||||
void sk_set_tbuf(sock *s, void *tbuf); /* Switch TX buffer, NULL-> return to internal */
|
void sk_set_tbuf(sock *s, void *tbuf); /* Switch TX buffer, NULL-> return to internal */
|
||||||
void sk_dump_all(void);
|
void sk_dump_all(struct dump_request *);
|
||||||
|
|
||||||
int sk_is_ipv4(sock *s); /* True if socket is IPv4 */
|
int sk_is_ipv4(sock *s); /* True if socket is IPv4 */
|
||||||
int sk_is_ipv6(sock *s); /* True if socket is IPv6 */
|
int sk_is_ipv6(sock *s); /* True if socket is IPv6 */
|
||||||
|
12
lib/timer.c
12
lib/timer.c
@ -102,19 +102,19 @@ tm_free(resource *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tm_dump(resource *r)
|
tm_dump(struct dump_request *dreq, resource *r)
|
||||||
{
|
{
|
||||||
timer *t = (void *) r;
|
timer *t = (void *) r;
|
||||||
|
|
||||||
debug("(code %p, data %p, ", t->hook, t->data);
|
RDUMP("(code %p, data %p, ", t->hook, t->data);
|
||||||
if (t->randomize)
|
if (t->randomize)
|
||||||
debug("rand %d, ", t->randomize);
|
RDUMP("rand %d, ", t->randomize);
|
||||||
if (t->recurrent)
|
if (t->recurrent)
|
||||||
debug("recur %ld, ", t->recurrent);
|
RDUMP("recur %ld, ", t->recurrent);
|
||||||
if (t->expires)
|
if (t->expires)
|
||||||
debug("expires in %ld ms)\n", (t->expires - current_time()) TO_MS);
|
RDUMP("expires in %ld ms)\n", (t->expires - current_time()) TO_MS);
|
||||||
else
|
else
|
||||||
debug("inactive)\n");
|
RDUMP("inactive)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -863,26 +863,25 @@ sym_args:
|
|||||||
| sym_args CF_SYM_KNOWN { $$ = $1; $$->sym = $2; }
|
| sym_args CF_SYM_KNOWN { $$ = $1; $$->sym = $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
CF_CLI_HELP(DUMP, ..., [[Dump debugging information to the given file]])
|
||||||
CF_CLI_HELP(DUMP, ..., [[Dump debugging information]])
|
CF_CLI(DUMP RESOURCES, text,, [[Dump all allocated resource]])
|
||||||
CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]])
|
{ cmd_dump_file(this_cli, $3, "resources", resource_dump); } ;
|
||||||
{ rdump(&root_pool); cli_msg(0, ""); } ;
|
CF_CLI(DUMP SOCKETS, text,, [[Dump open sockets]])
|
||||||
CF_CLI(DUMP SOCKETS,,, [[Dump open sockets]])
|
{ cmd_dump_file(this_cli, $3, "sockets", sk_dump_all); } ;
|
||||||
{ sk_dump_all(); cli_msg(0, ""); } ;
|
CF_CLI(DUMP EVENTS, text,, [[Dump event log]])
|
||||||
CF_CLI(DUMP EVENTS,,, [[Dump event log]])
|
{ cmd_dump_file(this_cli, $3, "event log", io_log_dump); } ;
|
||||||
{ io_log_dump(); cli_msg(0, ""); } ;
|
CF_CLI(DUMP INTERFACES, text,, [[Dump interface information]])
|
||||||
CF_CLI(DUMP INTERFACES,,, [[Dump interface information]])
|
{ cmd_dump_file(this_cli, $3, "interfaces", if_dump_all); } ;
|
||||||
{ if_dump_all(); cli_msg(0, ""); } ;
|
CF_CLI(DUMP NEIGHBORS, text,, [[Dump neighbor cache]])
|
||||||
CF_CLI(DUMP NEIGHBORS,,, [[Dump neighbor cache]])
|
{ cmd_dump_file(this_cli, $3, "neighbor cache", neigh_dump_all); } ;
|
||||||
{ neigh_dump_all(); cli_msg(0, ""); } ;
|
CF_CLI(DUMP ATTRIBUTES, text,, [[Dump attribute cache]])
|
||||||
CF_CLI(DUMP ATTRIBUTES,,, [[Dump attribute cache]])
|
{ cmd_dump_file(this_cli, $3, "attribute cache", rta_dump_all); } ;
|
||||||
{ rta_dump_all(); cli_msg(0, ""); } ;
|
CF_CLI(DUMP ROUTES, text,, [[Dump routing table]])
|
||||||
CF_CLI(DUMP ROUTES,,, [[Dump routing table]])
|
{ cmd_dump_file(this_cli, $3, "routing tables", rt_dump_all); } ;
|
||||||
{ rt_dump_all(); cli_msg(0, ""); } ;
|
CF_CLI(DUMP PROTOCOLS, text,, [[Dump protocol information]])
|
||||||
CF_CLI(DUMP PROTOCOLS,,, [[Dump protocol information]])
|
{ cmd_dump_file(this_cli, $3, "protocols", protos_dump_all); } ;
|
||||||
{ protos_dump_all(); cli_msg(0, ""); } ;
|
CF_CLI(DUMP FILTER ALL, text,, [[Dump all filters in linearized form]])
|
||||||
CF_CLI(DUMP FILTER ALL,,, [[Dump all filters in linearized form]])
|
{ cmd_dump_file(this_cli, $4, "filter bytecode", filters_dump_all); } ;
|
||||||
{ filters_dump_all(); cli_msg(0, ""); } ;
|
|
||||||
|
|
||||||
CF_CLI(EVAL, term, <expr>, [[Evaluate an expression]])
|
CF_CLI(EVAL, term, <expr>, [[Evaluate an expression]])
|
||||||
{ cmd_eval(f_linearize($2, 1)); } ;
|
{ cmd_eval(f_linearize($2, 1)); } ;
|
||||||
|
40
nest/iface.c
40
nest/iface.c
@ -47,9 +47,9 @@ static void if_recalc_preferred(struct iface *i);
|
|||||||
* This function dumps contents of an &ifa to the debug output.
|
* This function dumps contents of an &ifa to the debug output.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ifa_dump(struct ifa *a)
|
ifa_dump(struct dump_request *dreq, struct ifa *a)
|
||||||
{
|
{
|
||||||
debug("\t%I, net %N bc %I -> %I%s%s%s%s\n", a->ip, &a->prefix, a->brd, a->opposite,
|
RDUMP("\t%I, net %N bc %I -> %I%s%s%s%s\n", a->ip, &a->prefix, a->brd, a->opposite,
|
||||||
(a->flags & IA_PRIMARY) ? " PRIMARY" : "",
|
(a->flags & IA_PRIMARY) ? " PRIMARY" : "",
|
||||||
(a->flags & IA_SECONDARY) ? " SEC" : "",
|
(a->flags & IA_SECONDARY) ? " SEC" : "",
|
||||||
(a->flags & IA_HOST) ? " HOST" : "",
|
(a->flags & IA_HOST) ? " HOST" : "",
|
||||||
@ -64,35 +64,35 @@ ifa_dump(struct ifa *a)
|
|||||||
* network interface to the debug output.
|
* network interface to the debug output.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
if_dump(struct iface *i)
|
if_dump(struct dump_request *dreq, struct iface *i)
|
||||||
{
|
{
|
||||||
struct ifa *a;
|
struct ifa *a;
|
||||||
|
|
||||||
debug("IF%d: %s", i->index, i->name);
|
RDUMP("IF%d: %s", i->index, i->name);
|
||||||
if (i->flags & IF_SHUTDOWN)
|
if (i->flags & IF_SHUTDOWN)
|
||||||
debug(" SHUTDOWN");
|
RDUMP(" SHUTDOWN");
|
||||||
if (i->flags & IF_UP)
|
if (i->flags & IF_UP)
|
||||||
debug(" UP");
|
RDUMP(" UP");
|
||||||
else
|
else
|
||||||
debug(" DOWN");
|
RDUMP(" DOWN");
|
||||||
if (i->flags & IF_ADMIN_UP)
|
if (i->flags & IF_ADMIN_UP)
|
||||||
debug(" LINK-UP");
|
RDUMP(" LINK-UP");
|
||||||
if (i->flags & IF_MULTIACCESS)
|
if (i->flags & IF_MULTIACCESS)
|
||||||
debug(" MA");
|
RDUMP(" MA");
|
||||||
if (i->flags & IF_BROADCAST)
|
if (i->flags & IF_BROADCAST)
|
||||||
debug(" BC");
|
RDUMP(" BC");
|
||||||
if (i->flags & IF_MULTICAST)
|
if (i->flags & IF_MULTICAST)
|
||||||
debug(" MC");
|
RDUMP(" MC");
|
||||||
if (i->flags & IF_LOOPBACK)
|
if (i->flags & IF_LOOPBACK)
|
||||||
debug(" LOOP");
|
RDUMP(" LOOP");
|
||||||
if (i->flags & IF_IGNORE)
|
if (i->flags & IF_IGNORE)
|
||||||
debug(" IGN");
|
RDUMP(" IGN");
|
||||||
if (i->flags & IF_TMP_DOWN)
|
if (i->flags & IF_TMP_DOWN)
|
||||||
debug(" TDOWN");
|
RDUMP(" TDOWN");
|
||||||
debug(" MTU=%d\n", i->mtu);
|
RDUMP(" MTU=%d\n", i->mtu);
|
||||||
WALK_LIST(a, i->addrs)
|
WALK_LIST(a, i->addrs)
|
||||||
{
|
{
|
||||||
ifa_dump(a);
|
ifa_dump(dreq, a);
|
||||||
ASSERT(!!(a->flags & IA_PRIMARY) ==
|
ASSERT(!!(a->flags & IA_PRIMARY) ==
|
||||||
((a == i->addr4) || (a == i->addr6) || (a == i->llv6)));
|
((a == i->addr4) || (a == i->addr6) || (a == i->llv6)));
|
||||||
}
|
}
|
||||||
@ -105,14 +105,14 @@ if_dump(struct iface *i)
|
|||||||
* interfaces to the debug output.
|
* interfaces to the debug output.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
if_dump_all(void)
|
if_dump_all(struct dump_request *dreq)
|
||||||
{
|
{
|
||||||
struct iface *i;
|
struct iface *i;
|
||||||
|
|
||||||
debug("Known network interfaces:\n");
|
RDUMP("Known network interfaces:\n");
|
||||||
WALK_LIST(i, iface_list)
|
WALK_LIST(i, iface_list)
|
||||||
if_dump(i);
|
if_dump(dreq, i);
|
||||||
debug("Router ID: %08x\n", config->router_id);
|
RDUMP("Router ID: %08x\n", config->router_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned
|
static inline unsigned
|
||||||
|
10
nest/iface.h
10
nest/iface.h
@ -101,9 +101,9 @@ struct iface {
|
|||||||
#define IF_CHANGE_PREFERRED (IF_CHANGE_ADDR4 | IF_CHANGE_ADDR6 | IF_CHANGE_LLV6)
|
#define IF_CHANGE_PREFERRED (IF_CHANGE_ADDR4 | IF_CHANGE_ADDR6 | IF_CHANGE_LLV6)
|
||||||
|
|
||||||
void if_init(void);
|
void if_init(void);
|
||||||
void if_dump(struct iface *);
|
void if_dump(struct dump_request *dreq, struct iface *);
|
||||||
void if_dump_all(void);
|
void if_dump_all(struct dump_request *);
|
||||||
void ifa_dump(struct ifa *);
|
void ifa_dump(struct dump_request *dreq, struct ifa *);
|
||||||
void if_show(void);
|
void if_show(void);
|
||||||
void if_show_summary(void);
|
void if_show_summary(void);
|
||||||
struct iface *if_update(struct iface *);
|
struct iface *if_update(struct iface *);
|
||||||
@ -148,8 +148,8 @@ typedef struct neighbor {
|
|||||||
|
|
||||||
neighbor *neigh_find(struct proto *p, ip_addr a, struct iface *ifa, uint flags);
|
neighbor *neigh_find(struct proto *p, ip_addr a, struct iface *ifa, uint flags);
|
||||||
|
|
||||||
void neigh_dump(neighbor *);
|
void neigh_dump(struct dump_request *, neighbor *);
|
||||||
void neigh_dump_all(void);
|
void neigh_dump_all(struct dump_request *);
|
||||||
void neigh_prune(void);
|
void neigh_prune(void);
|
||||||
void neigh_if_up(struct iface *);
|
void neigh_if_up(struct iface *);
|
||||||
void neigh_if_down(struct iface *);
|
void neigh_if_down(struct iface *);
|
||||||
|
@ -87,14 +87,14 @@ olock_free(resource *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
olock_dump(resource *r)
|
olock_dump(struct dump_request *dreq, resource *r)
|
||||||
{
|
{
|
||||||
struct object_lock *l = (struct object_lock *) r;
|
struct object_lock *l = (struct object_lock *) r;
|
||||||
static char *olock_states[] = { "free", "locked", "waiting", "event" };
|
static char *olock_states[] = { "free", "locked", "waiting", "event" };
|
||||||
|
|
||||||
debug("(%d:%s:%I:%I:%d:%d) [%s]\n", l->type, (l->iface ? l->iface->name : "?"), l->addr, l->addr_local, l->port, l->inst, olock_states[l->state]);
|
RDUMP("(%d:%s:%I:%I:%d:%d) [%s]\n", l->type, (l->iface ? l->iface->name : "?"), l->addr, l->addr_local, l->port, l->inst, olock_states[l->state]);
|
||||||
if (!EMPTY_LIST(l->waiters))
|
if (!EMPTY_LIST(l->waiters))
|
||||||
debug(" [wanted]\n");
|
RDUMP(" [wanted]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct resclass olock_class = {
|
static struct resclass olock_class = {
|
||||||
|
@ -275,17 +275,17 @@ neigh_find(struct proto *p, ip_addr a, struct iface *iface, uint flags)
|
|||||||
* This functions dumps the contents of a given neighbor entry to debug output.
|
* This functions dumps the contents of a given neighbor entry to debug output.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
neigh_dump(neighbor *n)
|
neigh_dump(struct dump_request *dreq, neighbor *n)
|
||||||
{
|
{
|
||||||
debug("%p %I %s %s ", n, n->addr,
|
RDUMP("%p %I %s %s ", n, n->addr,
|
||||||
n->iface ? n->iface->name : "[]",
|
n->iface ? n->iface->name : "[]",
|
||||||
n->ifreq ? n->ifreq->name : "[]");
|
n->ifreq ? n->ifreq->name : "[]");
|
||||||
debug("%s %p %08x scope %s", n->proto->name, n->data, n->aux, ip_scope_text(n->scope));
|
RDUMP("%s %p %08x scope %s", n->proto->name, n->data, n->aux, ip_scope_text(n->scope));
|
||||||
if (n->flags & NEF_STICKY)
|
if (n->flags & NEF_STICKY)
|
||||||
debug(" STICKY");
|
RDUMP(" STICKY");
|
||||||
if (n->flags & NEF_ONLINK)
|
if (n->flags & NEF_ONLINK)
|
||||||
debug(" ONLINK");
|
RDUMP(" ONLINK");
|
||||||
debug("\n");
|
RDUMP("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -294,16 +294,16 @@ neigh_dump(neighbor *n)
|
|||||||
* This function dumps the contents of the neighbor cache to debug output.
|
* This function dumps the contents of the neighbor cache to debug output.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
neigh_dump_all(void)
|
neigh_dump_all(struct dump_request *dreq)
|
||||||
{
|
{
|
||||||
neighbor *n;
|
neighbor *n;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
debug("Known neighbors:\n");
|
RDUMP("Known neighbors:\n");
|
||||||
for(i=0; i<NEIGH_HASH_SIZE; i++)
|
for(i=0; i<NEIGH_HASH_SIZE; i++)
|
||||||
WALK_LIST(n, neigh_hash_table[i])
|
WALK_LIST(n, neigh_hash_table[i])
|
||||||
neigh_dump(n);
|
neigh_dump(dreq, n);
|
||||||
debug("\n");
|
RDUMP("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
14
nest/proto.c
14
nest/proto.c
@ -1693,27 +1693,27 @@ channel_graceful_restart_unlock(struct channel *c)
|
|||||||
* the internals.
|
* the internals.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
protos_dump_all(void)
|
protos_dump_all(struct dump_request *dreq)
|
||||||
{
|
{
|
||||||
debug("Protocols:\n");
|
RDUMP("Protocols:\n");
|
||||||
|
|
||||||
struct proto *p;
|
struct proto *p;
|
||||||
WALK_LIST(p, proto_list)
|
WALK_LIST(p, proto_list)
|
||||||
{
|
{
|
||||||
debug(" protocol %s state %s\n", p->name, p_states[p->proto_state]);
|
RDUMP(" protocol %s state %s\n", p->name, p_states[p->proto_state]);
|
||||||
|
|
||||||
struct channel *c;
|
struct channel *c;
|
||||||
WALK_LIST(c, p->channels)
|
WALK_LIST(c, p->channels)
|
||||||
{
|
{
|
||||||
debug("\tTABLE %s\n", c->table->name);
|
RDUMP("\tTABLE %s\n", c->table->name);
|
||||||
if (c->in_filter)
|
if (c->in_filter)
|
||||||
debug("\tInput filter: %s\n", filter_name(c->in_filter));
|
RDUMP("\tInput filter: %s\n", filter_name(c->in_filter));
|
||||||
if (c->out_filter)
|
if (c->out_filter)
|
||||||
debug("\tOutput filter: %s\n", filter_name(c->out_filter));
|
RDUMP("\tOutput filter: %s\n", filter_name(c->out_filter));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->proto->dump && (p->proto_state != PS_DOWN))
|
if (p->proto->dump && (p->proto_state != PS_DOWN))
|
||||||
p->proto->dump(p);
|
p->proto->dump(p, dreq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ struct protocol {
|
|||||||
void (*postconfig)(struct proto_config *); /* After configuring each instance */
|
void (*postconfig)(struct proto_config *); /* After configuring each instance */
|
||||||
struct proto * (*init)(struct proto_config *); /* Create new instance */
|
struct proto * (*init)(struct proto_config *); /* Create new instance */
|
||||||
int (*reconfigure)(struct proto *, struct proto_config *); /* Try to reconfigure instance, returns success */
|
int (*reconfigure)(struct proto *, struct proto_config *); /* Try to reconfigure instance, returns success */
|
||||||
void (*dump)(struct proto *); /* Debugging dump */
|
void (*dump)(struct proto *, struct dump_request *); /* Debugging dump */
|
||||||
int (*start)(struct proto *); /* Start the instance */
|
int (*start)(struct proto *); /* Start the instance */
|
||||||
int (*shutdown)(struct proto *); /* Stop the instance */
|
int (*shutdown)(struct proto *); /* Stop the instance */
|
||||||
void (*cleanup)(struct proto *); /* Called after shutdown when protocol became hungry/down */
|
void (*cleanup)(struct proto *); /* Called after shutdown when protocol became hungry/down */
|
||||||
@ -93,7 +93,7 @@ void proto_build(struct protocol *); /* Called from protocol to register itself
|
|||||||
void protos_preconfig(struct config *);
|
void protos_preconfig(struct config *);
|
||||||
void protos_commit(struct config *new, struct config *old, int force_restart, int type);
|
void protos_commit(struct config *new, struct config *old, int force_restart, int type);
|
||||||
struct proto * proto_spawn(struct proto_config *cf, uint disabled);
|
struct proto * proto_spawn(struct proto_config *cf, uint disabled);
|
||||||
void protos_dump_all(void);
|
void protos_dump_all(struct dump_request *);
|
||||||
|
|
||||||
#define GA_UNKNOWN 0 /* Attribute not recognized */
|
#define GA_UNKNOWN 0 /* Attribute not recognized */
|
||||||
#define GA_NAME 1 /* Result = name */
|
#define GA_NAME 1 /* Result = name */
|
||||||
|
12
nest/route.h
12
nest/route.h
@ -332,13 +332,13 @@ void rt_refresh_begin(rtable *t, struct channel *c);
|
|||||||
void rt_refresh_end(rtable *t, struct channel *c);
|
void rt_refresh_end(rtable *t, struct channel *c);
|
||||||
void rt_modify_stale(rtable *t, struct channel *c);
|
void rt_modify_stale(rtable *t, struct channel *c);
|
||||||
void rt_schedule_prune(rtable *t);
|
void rt_schedule_prune(rtable *t);
|
||||||
void rte_dump(rte *);
|
void rte_dump(struct dump_request *, rte *);
|
||||||
void rte_free(rte *);
|
void rte_free(rte *);
|
||||||
rte *rte_do_cow(rte *);
|
rte *rte_do_cow(rte *);
|
||||||
static inline rte * rte_cow(rte *r) { return (r->flags & REF_COW) ? rte_do_cow(r) : r; }
|
static inline rte * rte_cow(rte *r) { return (r->flags & REF_COW) ? rte_do_cow(r) : r; }
|
||||||
rte *rte_cow_rta(rte *r, linpool *lp);
|
rte *rte_cow_rta(rte *r, linpool *lp);
|
||||||
void rt_dump(rtable *);
|
void rt_dump(struct dump_request *, rtable *);
|
||||||
void rt_dump_all(void);
|
void rt_dump_all(struct dump_request *);
|
||||||
int rt_feed_channel(struct channel *c);
|
int rt_feed_channel(struct channel *c);
|
||||||
void rt_feed_channel_abort(struct channel *c);
|
void rt_feed_channel_abort(struct channel *c);
|
||||||
int rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *src);
|
int rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *src);
|
||||||
@ -608,7 +608,7 @@ struct ea_walk_state {
|
|||||||
eattr *ea_find(ea_list *, unsigned ea);
|
eattr *ea_find(ea_list *, unsigned ea);
|
||||||
eattr *ea_walk(struct ea_walk_state *s, uint id, uint max);
|
eattr *ea_walk(struct ea_walk_state *s, uint id, uint max);
|
||||||
uintptr_t ea_get_int(ea_list *, unsigned ea, uintptr_t def);
|
uintptr_t ea_get_int(ea_list *, unsigned ea, uintptr_t def);
|
||||||
void ea_dump(ea_list *);
|
void ea_dump(struct dump_request *, ea_list *);
|
||||||
void ea_sort(ea_list *); /* Sort entries in all sub-lists */
|
void ea_sort(ea_list *); /* Sort entries in all sub-lists */
|
||||||
unsigned ea_scan(ea_list *); /* How many bytes do we need for merged ea_list */
|
unsigned ea_scan(ea_list *); /* How many bytes do we need for merged ea_list */
|
||||||
void ea_merge(ea_list *from, ea_list *to); /* Merge sub-lists to allocated buffer */
|
void ea_merge(ea_list *from, ea_list *to); /* Merge sub-lists to allocated buffer */
|
||||||
@ -718,8 +718,8 @@ void rta__free(rta *r);
|
|||||||
static inline void rta_free(rta *r) { if (r && !--r->uc) rta__free(r); }
|
static inline void rta_free(rta *r) { if (r && !--r->uc) rta__free(r); }
|
||||||
rta *rta_do_cow(rta *o, linpool *lp);
|
rta *rta_do_cow(rta *o, linpool *lp);
|
||||||
static inline rta * rta_cow(rta *r, linpool *lp) { return rta_is_cached(r) ? rta_do_cow(r, lp) : r; }
|
static inline rta * rta_cow(rta *r, linpool *lp) { return rta_is_cached(r) ? rta_do_cow(r, lp) : r; }
|
||||||
void rta_dump(rta *);
|
void rta_dump(struct dump_request *, rta *);
|
||||||
void rta_dump_all(void);
|
void rta_dump_all(struct dump_request *);
|
||||||
void rta_show(struct cli *, rta *);
|
void rta_show(struct cli *, rta *);
|
||||||
|
|
||||||
u32 rt_get_igp_metric(rte *rt);
|
u32 rt_get_igp_metric(rte *rt);
|
||||||
|
@ -1044,40 +1044,40 @@ ea_show(struct cli *c, const eattr *e)
|
|||||||
* the debug output.
|
* the debug output.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ea_dump(ea_list *e)
|
ea_dump(struct dump_request *dreq, ea_list *e)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!e)
|
if (!e)
|
||||||
{
|
{
|
||||||
debug("NONE");
|
RDUMP("NONE");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (e)
|
while (e)
|
||||||
{
|
{
|
||||||
debug("[%c%c%c]",
|
RDUMP("[%c%c%c]",
|
||||||
(e->flags & EALF_SORTED) ? 'S' : 's',
|
(e->flags & EALF_SORTED) ? 'S' : 's',
|
||||||
(e->flags & EALF_BISECT) ? 'B' : 'b',
|
(e->flags & EALF_BISECT) ? 'B' : 'b',
|
||||||
(e->flags & EALF_CACHED) ? 'C' : 'c');
|
(e->flags & EALF_CACHED) ? 'C' : 'c');
|
||||||
for(i=0; i<e->count; i++)
|
for(i=0; i<e->count; i++)
|
||||||
{
|
{
|
||||||
eattr *a = &e->attrs[i];
|
eattr *a = &e->attrs[i];
|
||||||
debug(" %02x:%02x.%02x", EA_PROTO(a->id), EA_ID(a->id), a->flags);
|
RDUMP(" %02x:%02x.%02x", EA_PROTO(a->id), EA_ID(a->id), a->flags);
|
||||||
debug("=%c", "?iO?I?P???S?????" [a->type & EAF_TYPE_MASK]);
|
RDUMP("=%c", "?iO?I?P???S?????" [a->type & EAF_TYPE_MASK]);
|
||||||
if (a->originated)
|
if (a->originated)
|
||||||
debug("o");
|
RDUMP("o");
|
||||||
if (a->type & EAF_EMBEDDED)
|
if (a->type & EAF_EMBEDDED)
|
||||||
debug(":%08x", a->u.data);
|
RDUMP(":%08x", a->u.data);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int j, len = a->u.ptr->length;
|
int j, len = a->u.ptr->length;
|
||||||
debug("[%d]:", len);
|
RDUMP("[%d]:", len);
|
||||||
for(j=0; j<len; j++)
|
for(j=0; j<len; j++)
|
||||||
debug("%02x", a->u.ptr->data[j]);
|
RDUMP("%02x", a->u.ptr->data[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e = e->next)
|
if (e = e->next)
|
||||||
debug(" | ");
|
RDUMP(" | ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1317,7 +1317,7 @@ rta_do_cow(rta *o, linpool *lp)
|
|||||||
* This function takes a &rta and dumps its contents to the debug output.
|
* This function takes a &rta and dumps its contents to the debug output.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
rta_dump(rta *a)
|
rta_dump(struct dump_request *dreq, rta *a)
|
||||||
{
|
{
|
||||||
static char *rts[] = { "", "RTS_STATIC", "RTS_INHERIT", "RTS_DEVICE",
|
static char *rts[] = { "", "RTS_STATIC", "RTS_INHERIT", "RTS_DEVICE",
|
||||||
"RTS_STAT_DEV", "RTS_REDIR", "RTS_RIP",
|
"RTS_STAT_DEV", "RTS_REDIR", "RTS_RIP",
|
||||||
@ -1326,25 +1326,25 @@ rta_dump(rta *a)
|
|||||||
"RTS_RPKI", "RTS_PERF", "RTS_AGGREGATED", };
|
"RTS_RPKI", "RTS_PERF", "RTS_AGGREGATED", };
|
||||||
static char *rtd[] = { "", " DEV", " HOLE", " UNREACH", " PROHIBIT" };
|
static char *rtd[] = { "", " DEV", " HOLE", " UNREACH", " PROHIBIT" };
|
||||||
|
|
||||||
debug("pref=%d uc=%d %s %s%s h=%04x",
|
RDUMP("pref=%d uc=%d %s %s%s h=%04x",
|
||||||
a->pref, a->uc, rts[a->source], ip_scope_text(a->scope),
|
a->pref, a->uc, rts[a->source], ip_scope_text(a->scope),
|
||||||
rtd[a->dest], a->hash_key);
|
rtd[a->dest], a->hash_key);
|
||||||
if (!a->cached)
|
if (!a->cached)
|
||||||
debug(" !CACHED");
|
RDUMP(" !CACHED");
|
||||||
debug(" <-%I", a->from);
|
RDUMP(" <-%I", a->from);
|
||||||
if (a->dest == RTD_UNICAST)
|
if (a->dest == RTD_UNICAST)
|
||||||
for (struct nexthop *nh = &(a->nh); nh; nh = nh->next)
|
for (struct nexthop *nh = &(a->nh); nh; nh = nh->next)
|
||||||
{
|
{
|
||||||
if (ipa_nonzero(nh->gw)) debug(" ->%I", nh->gw);
|
if (ipa_nonzero(nh->gw)) RDUMP(" ->%I", nh->gw);
|
||||||
if (nh->labels) debug(" L %d", nh->label[0]);
|
if (nh->labels) RDUMP(" L %d", nh->label[0]);
|
||||||
for (int i=1; i<nh->labels; i++)
|
for (int i=1; i<nh->labels; i++)
|
||||||
debug("/%d", nh->label[i]);
|
RDUMP("/%d", nh->label[i]);
|
||||||
debug(" [%s]", nh->iface ? nh->iface->name : "???");
|
RDUMP(" [%s]", nh->iface ? nh->iface->name : "???");
|
||||||
}
|
}
|
||||||
if (a->eattrs)
|
if (a->eattrs)
|
||||||
{
|
{
|
||||||
debug(" EA: ");
|
RDUMP(" EA: ");
|
||||||
ea_dump(a->eattrs);
|
ea_dump(dreq, a->eattrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1355,20 +1355,20 @@ rta_dump(rta *a)
|
|||||||
* to the debug output.
|
* to the debug output.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
rta_dump_all(void)
|
rta_dump_all(struct dump_request *dreq)
|
||||||
{
|
{
|
||||||
rta *a;
|
rta *a;
|
||||||
uint h;
|
uint h;
|
||||||
|
|
||||||
debug("Route attribute cache (%d entries, rehash at %d):\n", rta_cache_count, rta_cache_limit);
|
RDUMP("Route attribute cache (%d entries, rehash at %d):\n", rta_cache_count, rta_cache_limit);
|
||||||
for(h=0; h<rta_cache_size; h++)
|
for(h=0; h<rta_cache_size; h++)
|
||||||
for(a=rta_hash_table[h]; a; a=a->next)
|
for(a=rta_hash_table[h]; a; a=a->next)
|
||||||
{
|
{
|
||||||
debug("%p ", a);
|
RDUMP("%p ", a);
|
||||||
rta_dump(a);
|
rta_dump(dreq, a);
|
||||||
debug("\n");
|
RDUMP("\n");
|
||||||
}
|
}
|
||||||
debug("\n");
|
RDUMP("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1751,13 +1751,13 @@ rt_modify_stale(rtable *t, struct channel *c)
|
|||||||
* This functions dumps contents of a &rte to debug output.
|
* This functions dumps contents of a &rte to debug output.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
rte_dump(rte *e)
|
rte_dump(struct dump_request *dreq, rte *e)
|
||||||
{
|
{
|
||||||
net *n = e->net;
|
net *n = e->net;
|
||||||
debug("%-1N ", n->n.addr);
|
RDUMP("%-1N ", n->n.addr);
|
||||||
debug("PF=%02x ", e->pflags);
|
RDUMP("PF=%02x ", e->pflags);
|
||||||
rta_dump(e->attrs);
|
rta_dump(dreq, e->attrs);
|
||||||
debug("\n");
|
RDUMP("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1767,9 +1767,9 @@ rte_dump(rte *e)
|
|||||||
* This function dumps contents of a given routing table to debug output.
|
* This function dumps contents of a given routing table to debug output.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
rt_dump(rtable *t)
|
rt_dump(struct dump_request *dreq, rtable *t)
|
||||||
{
|
{
|
||||||
debug("Dump of routing table <%s>\n", t->name);
|
RDUMP("Dump of routing table <%s>\n", t->name);
|
||||||
#ifdef DEBUGGING
|
#ifdef DEBUGGING
|
||||||
fib_check(&t->fib);
|
fib_check(&t->fib);
|
||||||
#endif
|
#endif
|
||||||
@ -1777,10 +1777,10 @@ rt_dump(rtable *t)
|
|||||||
{
|
{
|
||||||
rte *e;
|
rte *e;
|
||||||
for(e=n->routes; e; e=e->next)
|
for(e=n->routes; e; e=e->next)
|
||||||
rte_dump(e);
|
rte_dump(dreq, e);
|
||||||
}
|
}
|
||||||
FIB_WALK_END;
|
FIB_WALK_END;
|
||||||
debug("\n");
|
RDUMP("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1789,13 +1789,13 @@ rt_dump(rtable *t)
|
|||||||
* This function dumps contents of all routing tables to debug output.
|
* This function dumps contents of all routing tables to debug output.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
rt_dump_all(void)
|
rt_dump_all(struct dump_request *dreq)
|
||||||
{
|
{
|
||||||
rtable *t;
|
rtable *t;
|
||||||
node *n;
|
node *n;
|
||||||
|
|
||||||
WALK_LIST2(t, n, routing_tables, n)
|
WALK_LIST2(t, n, routing_tables, n)
|
||||||
rt_dump(t);
|
rt_dump(dreq, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -2057,10 +2057,10 @@ rt_free(resource *_r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rt_res_dump(resource *_r)
|
rt_res_dump(struct dump_request *dreq, resource *_r)
|
||||||
{
|
{
|
||||||
rtable *r = (rtable *) _r;
|
rtable *r = (rtable *) _r;
|
||||||
debug("name \"%s\", addr_type=%s, rt_count=%u, use_count=%d\n",
|
RDUMP("name \"%s\", addr_type=%s, rt_count=%u, use_count=%d\n",
|
||||||
r->name, net_label[r->addr_type], r->rt_count, r->use_count);
|
r->name, net_label[r->addr_type], r->rt_count, r->use_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2103,82 +2103,82 @@ babel_reconfigure_ifaces(struct babel_proto *p, struct babel_config *cf)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
babel_dump_source(struct babel_source *s)
|
babel_dump_source(struct dump_request *dreq, struct babel_source *s)
|
||||||
{
|
{
|
||||||
debug("Source router_id %lR seqno %d metric %d expires %t\n",
|
RDUMP("Source router_id %lR seqno %d metric %d expires %t\n",
|
||||||
s->router_id, s->seqno, s->metric,
|
s->router_id, s->seqno, s->metric,
|
||||||
s->expires ? s->expires - current_time() : 0);
|
s->expires ? s->expires - current_time() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
babel_dump_route(struct babel_route *r)
|
babel_dump_route(struct dump_request *dreq, struct babel_route *r)
|
||||||
{
|
{
|
||||||
debug("Route neigh %I if %s seqno %d metric %d/%d router_id %lR expires %t\n",
|
RDUMP("Route neigh %I if %s seqno %d metric %d/%d router_id %lR expires %t\n",
|
||||||
r->neigh->addr, r->neigh->ifa->ifname, r->seqno, r->advert_metric, r->metric,
|
r->neigh->addr, r->neigh->ifa->ifname, r->seqno, r->advert_metric, r->metric,
|
||||||
r->router_id, r->expires ? r->expires - current_time() : 0);
|
r->router_id, r->expires ? r->expires - current_time() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
babel_dump_entry(struct babel_entry *e)
|
babel_dump_entry(struct dump_request *dreq, struct babel_entry *e)
|
||||||
{
|
{
|
||||||
struct babel_source *s;
|
struct babel_source *s;
|
||||||
struct babel_route *r;
|
struct babel_route *r;
|
||||||
|
|
||||||
debug("Babel: Entry %N:\n", e->n.addr);
|
RDUMP("Babel: Entry %N:\n", e->n.addr);
|
||||||
|
|
||||||
WALK_LIST(s,e->sources)
|
WALK_LIST(s,e->sources)
|
||||||
{ debug(" "); babel_dump_source(s); }
|
{ RDUMP(" "); babel_dump_source(dreq, s); }
|
||||||
|
|
||||||
WALK_LIST(r,e->routes)
|
WALK_LIST(r,e->routes)
|
||||||
{
|
{
|
||||||
debug(" ");
|
RDUMP(" ");
|
||||||
if (r == e->selected) debug("*");
|
if (r == e->selected) RDUMP("*");
|
||||||
babel_dump_route(r);
|
babel_dump_route(dreq, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
babel_dump_neighbor(struct babel_neighbor *n)
|
babel_dump_neighbor(struct dump_request *dreq, struct babel_neighbor *n)
|
||||||
{
|
{
|
||||||
debug("Neighbor %I txcost %d hello_map %x next seqno %d expires %t/%t\n",
|
RDUMP("Neighbor %I txcost %d hello_map %x next seqno %d expires %t/%t\n",
|
||||||
n->addr, n->txcost, n->hello_map, n->next_hello_seqno,
|
n->addr, n->txcost, n->hello_map, n->next_hello_seqno,
|
||||||
n->hello_expiry ? n->hello_expiry - current_time() : 0,
|
n->hello_expiry ? n->hello_expiry - current_time() : 0,
|
||||||
n->ihu_expiry ? n->ihu_expiry - current_time() : 0);
|
n->ihu_expiry ? n->ihu_expiry - current_time() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
babel_dump_iface(struct babel_iface *ifa)
|
babel_dump_iface(struct dump_request *dreq, struct babel_iface *ifa)
|
||||||
{
|
{
|
||||||
struct babel_neighbor *n;
|
struct babel_neighbor *n;
|
||||||
|
|
||||||
debug("Babel: Interface %s addr %I rxcost %d type %d hello seqno %d intervals %t %t",
|
RDUMP("Babel: Interface %s addr %I rxcost %d type %d hello seqno %d intervals %t %t",
|
||||||
ifa->ifname, ifa->addr, ifa->cf->rxcost, ifa->cf->type, ifa->hello_seqno,
|
ifa->ifname, ifa->addr, ifa->cf->rxcost, ifa->cf->type, ifa->hello_seqno,
|
||||||
ifa->cf->hello_interval, ifa->cf->update_interval);
|
ifa->cf->hello_interval, ifa->cf->update_interval);
|
||||||
debug(" next hop v4 %I next hop v6 %I\n", ifa->next_hop_ip4, ifa->next_hop_ip6);
|
RDUMP(" next hop v4 %I next hop v6 %I\n", ifa->next_hop_ip4, ifa->next_hop_ip6);
|
||||||
|
|
||||||
WALK_LIST(n, ifa->neigh_list)
|
WALK_LIST(n, ifa->neigh_list)
|
||||||
{ debug(" "); babel_dump_neighbor(n); }
|
{ RDUMP(" "); babel_dump_neighbor(dreq, n); }
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
babel_dump(struct proto *P)
|
babel_dump(struct proto *P, struct dump_request *dreq)
|
||||||
{
|
{
|
||||||
struct babel_proto *p = (struct babel_proto *) P;
|
struct babel_proto *p = (struct babel_proto *) P;
|
||||||
struct babel_iface *ifa;
|
struct babel_iface *ifa;
|
||||||
|
|
||||||
debug("Babel: router id %lR update seqno %d\n", p->router_id, p->update_seqno);
|
RDUMP("Babel: router id %lR update seqno %d\n", p->router_id, p->update_seqno);
|
||||||
|
|
||||||
WALK_LIST(ifa, p->interfaces)
|
WALK_LIST(ifa, p->interfaces)
|
||||||
babel_dump_iface(ifa);
|
babel_dump_iface(dreq, ifa);
|
||||||
|
|
||||||
FIB_WALK(&p->ip4_rtable, struct babel_entry, e)
|
FIB_WALK(&p->ip4_rtable, struct babel_entry, e)
|
||||||
{
|
{
|
||||||
babel_dump_entry(e);
|
babel_dump_entry(dreq, e);
|
||||||
}
|
}
|
||||||
FIB_WALK_END;
|
FIB_WALK_END;
|
||||||
FIB_WALK(&p->ip6_rtable, struct babel_entry, e)
|
FIB_WALK(&p->ip6_rtable, struct babel_entry, e)
|
||||||
{
|
{
|
||||||
babel_dump_entry(e);
|
babel_dump_entry(dreq, e);
|
||||||
}
|
}
|
||||||
FIB_WALK_END;
|
FIB_WALK_END;
|
||||||
}
|
}
|
||||||
|
@ -826,11 +826,11 @@ bfd_request_free(resource *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bfd_request_dump(resource *r)
|
bfd_request_dump(struct dump_request *dreq, resource *r)
|
||||||
{
|
{
|
||||||
struct bfd_request *req = (struct bfd_request *) r;
|
struct bfd_request *req = (struct bfd_request *) r;
|
||||||
|
|
||||||
debug("(code %p, data %p)\n", req->hook, req->data);
|
RDUMP("(code %p, data %p)\n", req->hook, req->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct resclass bfd_request_class = {
|
static struct resclass bfd_request_class = {
|
||||||
|
@ -237,7 +237,7 @@ static void
|
|||||||
bmp_tx_resource_free(resource *r UNUSED) {}
|
bmp_tx_resource_free(resource *r UNUSED) {}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bmp_tx_resource_dump(resource *r UNUSED) {}
|
bmp_tx_resource_dump(struct dump_request *dreq UNUSED, resource *r UNUSED) {}
|
||||||
|
|
||||||
static struct resmem
|
static struct resmem
|
||||||
bmp_tx_resource_memsize(resource *r)
|
bmp_tx_resource_memsize(resource *r)
|
||||||
|
@ -333,32 +333,31 @@ ospf_start(struct proto *P)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ospf_dump(struct proto *P)
|
ospf_dump(struct proto *P, struct dump_request *dreq)
|
||||||
{
|
{
|
||||||
struct ospf_proto *p = (struct ospf_proto *) P;
|
struct ospf_proto *p = (struct ospf_proto *) P;
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
struct ospf_neighbor *n;
|
struct ospf_neighbor *n;
|
||||||
|
|
||||||
OSPF_TRACE(D_EVENTS, "Area number: %d", p->areano);
|
RDUMP("Area number: %d\n", p->areano);
|
||||||
|
|
||||||
WALK_LIST(ifa, p->iface_list)
|
WALK_LIST(ifa, p->iface_list)
|
||||||
{
|
{
|
||||||
OSPF_TRACE(D_EVENTS, "Interface: %s", ifa->ifname);
|
RDUMP("Interface: %s\n", ifa->ifname);
|
||||||
OSPF_TRACE(D_EVENTS, "state: %u", ifa->state);
|
RDUMP("state: %u\n", ifa->state);
|
||||||
OSPF_TRACE(D_EVENTS, "DR: %R", ifa->drid);
|
RDUMP("DR: %R\n", ifa->drid);
|
||||||
OSPF_TRACE(D_EVENTS, "BDR: %R", ifa->bdrid);
|
RDUMP("BDR: %R\n", ifa->bdrid);
|
||||||
WALK_LIST(n, ifa->neigh_list)
|
WALK_LIST(n, ifa->neigh_list)
|
||||||
{
|
{
|
||||||
OSPF_TRACE(D_EVENTS, " neighbor %R in state %u", n->rid, n->state);
|
RDUMP(" neighbor %R in state %u\n", n->rid, n->state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
OSPF_TRACE(D_EVENTS, "LSA graph dump start:");
|
RDUMP("LSA graph dump start:");
|
||||||
ospf_top_dump(p->gr, p);
|
ospf_top_dump(p->gr, p);
|
||||||
OSPF_TRACE(D_EVENTS, "LSA graph dump finished");
|
RDUMP("LSA graph dump finished");
|
||||||
*/
|
*/
|
||||||
neigh_dump_all();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct proto *
|
static struct proto *
|
||||||
|
@ -1315,7 +1315,7 @@ rip_show_neighbors(struct proto *P, const char *iff)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rip_dump(struct proto *P)
|
rip_dump(struct proto *P, struct dump_request *dreq)
|
||||||
{
|
{
|
||||||
struct rip_proto *p = (struct rip_proto *) P;
|
struct rip_proto *p = (struct rip_proto *) P;
|
||||||
struct rip_iface *ifa;
|
struct rip_iface *ifa;
|
||||||
@ -1324,12 +1324,12 @@ rip_dump(struct proto *P)
|
|||||||
i = 0;
|
i = 0;
|
||||||
FIB_WALK(&p->rtable, struct rip_entry, en)
|
FIB_WALK(&p->rtable, struct rip_entry, en)
|
||||||
{
|
{
|
||||||
debug("RIP: entry #%d: %N via %I dev %s valid %d metric %d age %t\n",
|
RDUMP("RIP: entry #%d: %N via %I dev %s valid %d metric %d age %t\n",
|
||||||
i++, en->n.addr, en->next_hop, en->iface ? en->iface->name : "(null)",
|
i++, en->n.addr, en->next_hop, en->iface ? en->iface->name : "(null)",
|
||||||
en->valid, en->metric, current_time() - en->changed);
|
en->valid, en->metric, current_time() - en->changed);
|
||||||
|
|
||||||
for (struct rip_rte *e = en->routes; e; e = e->next)
|
for (struct rip_rte *e = en->routes; e; e = e->next)
|
||||||
debug("RIP: via %I metric %d expires %t\n",
|
RDUMP("RIP: via %I metric %d expires %t\n",
|
||||||
e->next_hop, e->metric, e->expires - current_time());
|
e->next_hop, e->metric, e->expires - current_time());
|
||||||
}
|
}
|
||||||
FIB_WALK_END;
|
FIB_WALK_END;
|
||||||
@ -1337,7 +1337,7 @@ rip_dump(struct proto *P)
|
|||||||
i = 0;
|
i = 0;
|
||||||
WALK_LIST(ifa, p->iface_list)
|
WALK_LIST(ifa, p->iface_list)
|
||||||
{
|
{
|
||||||
debug("RIP: interface #%d: %s, %I, up = %d, busy = %d\n",
|
RDUMP("RIP: interface #%d: %s, %I, up = %d, busy = %d\n",
|
||||||
i++, ifa->iface->name, ifa->sk ? ifa->sk->daddr : IPA_NONE,
|
i++, ifa->iface->name, ifa->sk ? ifa->sk->daddr : IPA_NONE,
|
||||||
ifa->up, ifa->tx_active);
|
ifa->up, ifa->tx_active);
|
||||||
}
|
}
|
||||||
|
@ -613,27 +613,27 @@ static_cleanup(struct proto *P)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
static_dump_rte(struct static_route *r)
|
static_dump_rte(struct dump_request *dreq, struct static_route *r)
|
||||||
{
|
{
|
||||||
debug("%-1N (%u): ", r->net, r->index);
|
RDUMP("%-1N (%u): ", r->net, r->index);
|
||||||
if (r->dest == RTD_UNICAST)
|
if (r->dest == RTD_UNICAST)
|
||||||
if (r->iface && ipa_zero(r->via))
|
if (r->iface && ipa_zero(r->via))
|
||||||
debug("dev %s\n", r->iface->name);
|
RDUMP("dev %s\n", r->iface->name);
|
||||||
else
|
else
|
||||||
debug("via %I%J\n", r->via, r->iface);
|
RDUMP("via %I%J\n", r->via, r->iface);
|
||||||
else
|
else
|
||||||
debug("rtd %d\n", r->dest);
|
RDUMP("rtd %d\n", r->dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
static_dump(struct proto *P)
|
static_dump(struct proto *P, struct dump_request *dreq)
|
||||||
{
|
{
|
||||||
struct static_config *c = (void *) P->cf;
|
struct static_config *c = (void *) P->cf;
|
||||||
struct static_route *r;
|
struct static_route *r;
|
||||||
|
|
||||||
debug("Static routes:\n");
|
RDUMP("Static routes:\n");
|
||||||
WALK_LIST(r, c->routes)
|
WALK_LIST(r, c->routes)
|
||||||
static_dump_rte(r);
|
static_dump_rte(dreq, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IGP_TABLE(cf, sym) ((cf)->igp_table_##sym ? (cf)->igp_table_##sym ->table : NULL )
|
#define IGP_TABLE(cf, sym) ((cf)->igp_table_##sym ? (cf)->igp_table_##sym ->table : NULL )
|
||||||
|
@ -226,6 +226,26 @@ global_free_pages_cleanup_event(void *data UNUSED)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
page_dump(struct dump_request *dreq)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_MMAP
|
||||||
|
RDUMP("Hot pages:\n");
|
||||||
|
node *n;
|
||||||
|
WALK_LIST(n, global_free_pages.pages)
|
||||||
|
RDUMP(" %p\n", n);
|
||||||
|
|
||||||
|
RDUMP("Cold pages:\n");
|
||||||
|
WALK_LIST(n, global_free_pages.empty)
|
||||||
|
{
|
||||||
|
struct empty_pages *ep = SKIP_BACK(struct empty_pages, n, n);
|
||||||
|
RDUMP(" %p (index)\n", ep);
|
||||||
|
for (uint i=0; i<ep->pos; i++)
|
||||||
|
RDUMP(" %p\n", ep->pages[i]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
resource_sys_init(void)
|
resource_sys_init(void)
|
||||||
{
|
{
|
||||||
|
167
sysdep/unix/io.c
167
sysdep/unix/io.c
@ -19,6 +19,7 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
@ -40,6 +41,7 @@
|
|||||||
#include "lib/timer.h"
|
#include "lib/timer.h"
|
||||||
#include "lib/string.h"
|
#include "lib/string.h"
|
||||||
#include "nest/iface.h"
|
#include "nest/iface.h"
|
||||||
|
#include "nest/cli.h"
|
||||||
#include "conf/conf.h"
|
#include "conf/conf.h"
|
||||||
|
|
||||||
#include "sysdep/unix/unix.h"
|
#include "sysdep/unix/unix.h"
|
||||||
@ -75,11 +77,11 @@ rf_free(resource *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rf_dump(resource *r)
|
rf_dump(struct dump_request *dreq, resource *r)
|
||||||
{
|
{
|
||||||
struct rfile *a = (struct rfile *) r;
|
struct rfile *a = (struct rfile *) r;
|
||||||
|
|
||||||
debug("(FILE *%p)\n", a->f);
|
RDUMP("(FILE *%p)\n", a->f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct resclass rf_class = {
|
static struct resclass rf_class = {
|
||||||
@ -129,6 +131,147 @@ rf_fileno(struct rfile *f)
|
|||||||
return fileno(f->f);
|
return fileno(f->f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dumping to files
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct dump_request_file {
|
||||||
|
struct dump_request dr;
|
||||||
|
uint pos, max; int fd;
|
||||||
|
uint last_progress_info;
|
||||||
|
char data[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_to_file_flush(struct dump_request_file *req)
|
||||||
|
{
|
||||||
|
if (req->fd < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (uint sent = 0; sent < req->pos; )
|
||||||
|
{
|
||||||
|
int e = write(req->fd, &req->data[sent], req->pos - sent);
|
||||||
|
if (e <= 0)
|
||||||
|
{
|
||||||
|
req->dr.report(&req->dr, 8009, "Failed to write data: %m");
|
||||||
|
close(req->fd);
|
||||||
|
req->fd = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sent += e;
|
||||||
|
}
|
||||||
|
|
||||||
|
req->dr.size += req->pos;
|
||||||
|
req->pos = 0;
|
||||||
|
|
||||||
|
for (uint reported = 0; req->dr.size >> req->last_progress_info; req->last_progress_info++)
|
||||||
|
if (!reported++)
|
||||||
|
req->dr.report(&req->dr, -13, "... dumped %lu bytes in %t s",
|
||||||
|
req->dr.size, current_time_now() - req->dr.begin);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_to_file_write(struct dump_request *dr, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
struct dump_request_file *req = SKIP_BACK(struct dump_request_file, dr, dr);
|
||||||
|
|
||||||
|
for (uint phase = 0; (req->fd >= 0) && (phase < 2); phase++)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
int i = bvsnprintf(&req->data[req->pos], req->max - req->pos, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
if (i >= 0)
|
||||||
|
{
|
||||||
|
req->pos += i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dump_to_file_flush(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
bug("Too long dump call");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dump_request *
|
||||||
|
dump_to_file_init(off_t offset)
|
||||||
|
{
|
||||||
|
ASSERT_DIE(offset + sizeof(struct dump_request_file) + 1024 < (unsigned long) page_size);
|
||||||
|
|
||||||
|
struct dump_request_file *req = alloc_page() + offset;
|
||||||
|
*req = (struct dump_request_file) {
|
||||||
|
.dr = {
|
||||||
|
.write = dump_to_file_write,
|
||||||
|
.begin = current_time_now(),
|
||||||
|
.offset = offset,
|
||||||
|
},
|
||||||
|
.max = page_size - offset - OFFSETOF(struct dump_request_file, data[0]),
|
||||||
|
.fd = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
return &req->dr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dump_to_file_run(struct dump_request *dr, const char *file, const char *what, void (*dump)(struct dump_request *))
|
||||||
|
{
|
||||||
|
struct dump_request_file *req = SKIP_BACK(struct dump_request_file, dr, dr);
|
||||||
|
req->fd = open(file, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR);
|
||||||
|
|
||||||
|
if (req->fd < 0)
|
||||||
|
{
|
||||||
|
dr->report(dr, 8009, "Failed to open file %s: %m", file);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
dr->report(dr, -13, "Dumping %s to %s", what, file);
|
||||||
|
|
||||||
|
dump(dr);
|
||||||
|
|
||||||
|
if (req->fd >= 0)
|
||||||
|
{
|
||||||
|
dump_to_file_flush(req);
|
||||||
|
close(req->fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
btime end = current_time_now();
|
||||||
|
dr->report(dr, 13, "Dumped %lu bytes in %t s", dr->size, end - dr->begin);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
free_page(((void *) req) - dr->offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dump_request_cli {
|
||||||
|
cli *cli;
|
||||||
|
struct dump_request dr;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_dump_report(struct dump_request *dr, int state, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
struct dump_request_cli *req = SKIP_BACK(struct dump_request_cli, dr, dr);
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
cli_vprintf(req->cli, state, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cmd_dump_file(struct cli *cli, const char *file, const char *what, void (*dump)(struct dump_request *))
|
||||||
|
{
|
||||||
|
if (cli->restricted)
|
||||||
|
return cli_printf(cli, 8007, "Access denied");
|
||||||
|
|
||||||
|
struct dump_request_cli *req = SKIP_BACK(struct dump_request_cli, dr,
|
||||||
|
dump_to_file_init(OFFSETOF(struct dump_request_cli, dr)));
|
||||||
|
|
||||||
|
req->cli = cli;
|
||||||
|
req->dr.report = cmd_dump_report;
|
||||||
|
|
||||||
|
dump_to_file_run(&req->dr, file, what, dump);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Time clock
|
* Time clock
|
||||||
@ -932,12 +1075,12 @@ sk_reallocate(sock *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sk_dump(resource *r)
|
sk_dump(struct dump_request *dreq, resource *r)
|
||||||
{
|
{
|
||||||
sock *s = (sock *) r;
|
sock *s = (sock *) r;
|
||||||
static char *sk_type_names[] = { "TCP<", "TCP>", "TCP", "UDP", NULL, "IP", NULL, "MAGIC", "UNIX<", "UNIX", "SSH>", "SSH", "DEL!" };
|
static char *sk_type_names[] = { "TCP<", "TCP>", "TCP", "UDP", NULL, "IP", NULL, "MAGIC", "UNIX<", "UNIX", "SSH>", "SSH", "DEL!" };
|
||||||
|
|
||||||
debug("(%s, ud=%p, sa=%I, sp=%d, da=%I, dp=%d, tos=%d, ttl=%d, if=%s)\n",
|
RDUMP("(%s, ud=%p, sa=%I, sp=%d, da=%I, dp=%d, tos=%d, ttl=%d, if=%s)\n",
|
||||||
sk_type_names[s->type],
|
sk_type_names[s->type],
|
||||||
s->data,
|
s->data,
|
||||||
s->saddr,
|
s->saddr,
|
||||||
@ -2088,19 +2231,19 @@ sk_err(sock *s, int revents)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sk_dump_all(void)
|
sk_dump_all(struct dump_request *dreq)
|
||||||
{
|
{
|
||||||
node *n;
|
node *n;
|
||||||
sock *s;
|
sock *s;
|
||||||
|
|
||||||
debug("Open sockets:\n");
|
RDUMP("Open sockets:\n");
|
||||||
WALK_LIST(n, sock_list)
|
WALK_LIST(n, sock_list)
|
||||||
{
|
{
|
||||||
s = SKIP_BACK(sock, n, n);
|
s = SKIP_BACK(sock, n, n);
|
||||||
debug("%p ", s);
|
RDUMP("%p ", s);
|
||||||
sk_dump(&s->r);
|
sk_dump(dreq, &s->r);
|
||||||
}
|
}
|
||||||
debug("\n");
|
RDUMP("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2191,16 +2334,16 @@ io_close_event(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
io_log_dump(void)
|
io_log_dump(struct dump_request *dreq)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
log(L_DEBUG "Event log:");
|
RDUMP("Event log:");
|
||||||
for (i = 0; i < EVENT_LOG_LENGTH; i++)
|
for (i = 0; i < EVENT_LOG_LENGTH; i++)
|
||||||
{
|
{
|
||||||
struct event_log_entry *en = event_log + (event_log_pos + i) % EVENT_LOG_LENGTH;
|
struct event_log_entry *en = event_log + (event_log_pos + i) % EVENT_LOG_LENGTH;
|
||||||
if (en->hook)
|
if (en->hook)
|
||||||
log(L_DEBUG " Event 0x%p 0x%p at %8d for %d ms", en->hook, en->data,
|
RDUMP(" Event 0x%p 0x%p at %8d for %d ms", en->hook, en->data,
|
||||||
(int) ((last_time - en->timestamp) TO_MS), (int) (en->duration TO_MS));
|
(int) ((last_time - en->timestamp) TO_MS), (int) (en->duration TO_MS));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -532,14 +532,14 @@ krt_learn_init(struct krt_proto *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
krt_dump(struct proto *P)
|
krt_dump(struct proto *P, struct dump_request *dreq)
|
||||||
{
|
{
|
||||||
struct krt_proto *p = (struct krt_proto *) P;
|
struct krt_proto *p = (struct krt_proto *) P;
|
||||||
|
|
||||||
if (!KRT_CF->learn)
|
if (!KRT_CF->learn)
|
||||||
return;
|
return;
|
||||||
debug("KRT: Table of inheritable routes\n");
|
RDUMP("KRT: Table of inheritable routes\n");
|
||||||
rt_dump(p->krt_table);
|
rt_dump(dreq, p->krt_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,21 +48,38 @@
|
|||||||
* Debugging
|
* Debugging
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
async_dump_report(struct dump_request *dr UNUSED, int state, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vlog(((state > 1000) ? L_ERR : L_INFO)[0], fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
async_dump_run(struct dump_request *dreq)
|
||||||
|
{
|
||||||
|
RDUMP("ASYNC STATE DUMP\n");
|
||||||
|
|
||||||
|
rdump(dreq, &root_pool);
|
||||||
|
sk_dump_all(dreq);
|
||||||
|
// XXXX tm_dump_all();
|
||||||
|
if_dump_all(dreq);
|
||||||
|
neigh_dump_all(dreq);
|
||||||
|
rta_dump_all(dreq);
|
||||||
|
rt_dump_all(dreq);
|
||||||
|
protos_dump_all(dreq);
|
||||||
|
|
||||||
|
debug("\n");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
async_dump(void)
|
async_dump(void)
|
||||||
{
|
{
|
||||||
debug("INTERNAL STATE DUMP\n\n");
|
struct dump_request *dr = dump_to_file_init(0);
|
||||||
|
dr->report = async_dump_report;
|
||||||
rdump(&root_pool);
|
dump_to_file_run(dr, "bird.dump", "async dump", async_dump_run);
|
||||||
sk_dump_all();
|
|
||||||
// XXXX tm_dump_all();
|
|
||||||
if_dump_all();
|
|
||||||
neigh_dump_all();
|
|
||||||
rta_dump_all();
|
|
||||||
rt_dump_all();
|
|
||||||
protos_dump_all();
|
|
||||||
|
|
||||||
debug("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -16,6 +16,7 @@ struct pool;
|
|||||||
struct iface;
|
struct iface;
|
||||||
struct birdsock;
|
struct birdsock;
|
||||||
struct rfile;
|
struct rfile;
|
||||||
|
struct cli;
|
||||||
|
|
||||||
/* main.c */
|
/* main.c */
|
||||||
|
|
||||||
@ -106,7 +107,7 @@ extern volatile sig_atomic_t async_shutdown_flag;
|
|||||||
|
|
||||||
void io_init(void);
|
void io_init(void);
|
||||||
void io_loop(void);
|
void io_loop(void);
|
||||||
void io_log_dump(void);
|
void io_log_dump(struct dump_request *);
|
||||||
int sk_open_unix(struct birdsock *s, const char *name);
|
int sk_open_unix(struct birdsock *s, const char *name);
|
||||||
struct rfile *rf_open(struct pool *, const char *name, const char *mode);
|
struct rfile *rf_open(struct pool *, const char *name, const char *mode);
|
||||||
struct rfile *rf_fdopen(pool *p, int fd, const char *mode);
|
struct rfile *rf_fdopen(pool *p, int fd, const char *mode);
|
||||||
@ -115,6 +116,11 @@ int rf_fileno(struct rfile *f);
|
|||||||
void test_old_bird(const char *path);
|
void test_old_bird(const char *path);
|
||||||
ip_addr resolve_hostname(const char *host, int type, const char **err_msg);
|
ip_addr resolve_hostname(const char *host, int type, const char **err_msg);
|
||||||
|
|
||||||
|
struct dump_request *dump_to_file_init(off_t offset);
|
||||||
|
void dump_to_file_run(struct dump_request *dr, const char *file, const char *what, void (*dump)(struct dump_request *));
|
||||||
|
|
||||||
|
void cmd_dump_file(struct cli *cli, const char *file, const char *what, void (*dump)(struct dump_request *));
|
||||||
|
|
||||||
/* krt.c bits */
|
/* krt.c bits */
|
||||||
|
|
||||||
void krt_io_init(void);
|
void krt_io_init(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user