0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2025-01-20 16:01:53 +00:00

Merge commit 'ac5745134847c044b21c311e5ab11d92d05bacc1' into integrated

This commit is contained in:
Ondrej Zajicek 2013-07-31 18:36:55 +02:00
commit a013bd08e3
10 changed files with 89 additions and 23 deletions

View File

@ -282,7 +282,7 @@ protocol rip {
<tag>include "<m/filename/"</tag> <tag>include "<m/filename/"</tag>
This statement causes inclusion of a new file. The maximal depth is set to 5. This statement causes inclusion of a new file. The maximal depth is set to 5.
<tag>log "<m/filename/"|syslog [name <m/name/]|stderr all|{ <m/list of classes/ }</tag> <tag><label id="dsc-log">log "<m/filename/"|syslog [name <m/name/]|stderr all|{ <m/list of classes/ }</tag>
Set logging of messages having the given class (either <cf/all/ or <cf/{ Set logging of messages having the given class (either <cf/all/ or <cf/{
error, trace }/ etc.) into selected destination (a file specified as a filename string, error, trace }/ etc.) into selected destination (a file specified as a filename string,
syslog with optional name argument, or the stderr output). Classes are: syslog with optional name argument, or the stderr output). Classes are:
@ -651,9 +651,6 @@ This argument can be omitted if there exists only a single instance.
<p>Here is a brief list of supported functions: <p>Here is a brief list of supported functions:
<descrip> <descrip>
<tag>dump resources|sockets|interfaces|neighbors|attributes|routes|protocols</tag>
Dump contents of internal data structures to the debugging output.
<tag>show status</tag> <tag>show status</tag>
Show router status, that is BIRD version, uptime and time from last reconfiguration. Show router status, that is BIRD version, uptime and time from last reconfiguration.
@ -812,6 +809,17 @@ This argument can be omitted if there exists only a single instance.
<tag>debug <m/protocol/|<m/pattern/|all all|off|{ states | routes | filters | events | packets }</tag> <tag>debug <m/protocol/|<m/pattern/|all all|off|{ states | routes | filters | events | packets }</tag>
Control protocol debugging. Control protocol debugging.
<tag>dump resources|sockets|interfaces|neighbors|attributes|routes|protocols</tag>
Dump contents of internal data structures to the debugging output.
<tag>echo all|off|{ <m/list of log classes/ } [ <m/buffer-size/ ]</tag>
Control echoing of log messages to the command-line output.
See <ref id="dsc-log" name="log option"> for a list of log classes.
<tag>eval <m/expr/</tag>
Evaluate given expression.
</descrip> </descrip>
<chapt>Filters <chapt>Filters

View File

@ -31,6 +31,7 @@ Reply codes of BIRD command-line interface
0020 Configuration OK 0020 Configuration OK
0021 Undo requested 0021 Undo requested
0022 Undo scheduled 0022 Undo scheduled
0023 Evaluation of expression
1000 BIRD version 1000 BIRD version
1001 Interface list 1001 Interface list
@ -61,6 +62,7 @@ Reply codes of BIRD command-line interface
8005 Protocol is down => cannot dump 8005 Protocol is down => cannot dump
8006 Reload failed 8006 Reload failed
8007 Access denied 8007 Access denied
8008 Evaluation runtime error
9000 Command too long 9000 Command too long
9001 Parse error 9001 Parse error

View File

@ -440,8 +440,6 @@ val_in_range(struct f_val v1, struct f_val v2)
return CMP_ERROR; return CMP_ERROR;
} }
static void val_print(struct f_val v);
static void static void
tree_node_print(struct f_tree *t, char **sep) tree_node_print(struct f_tree *t, char **sep)
{ {
@ -474,7 +472,7 @@ tree_print(struct f_tree *t)
/* /*
* val_print - format filter value * val_print - format filter value
*/ */
static void void
val_print(struct f_val v) val_print(struct f_val v)
{ {
char buf2[1024]; char buf2[1024];
@ -558,6 +556,8 @@ static struct rate_limit rl_runtime_err;
#define TWOARGS_C TWOARGS \ #define TWOARGS_C TWOARGS \
if (v1.type != v2.type) \ if (v1.type != v2.type) \
runtime( "Can't operate with values of incompatible types" ); runtime( "Can't operate with values of incompatible types" );
#define ACCESS_RTE \
do { if (!f_rte) runtime("No route to access"); } while (0)
/** /**
* interpret * interpret
@ -821,6 +821,7 @@ interpret(struct f_inst *what)
break; break;
case 'a': /* rta access */ case 'a': /* rta access */
{ {
ACCESS_RTE;
struct rta *rta = (*f_rte)->attrs; struct rta *rta = (*f_rte)->attrs;
res.type = what->aux; res.type = what->aux;
switch(res.type) { switch(res.type) {
@ -845,6 +846,7 @@ interpret(struct f_inst *what)
} }
break; break;
case P('a','S'): case P('a','S'):
ACCESS_RTE;
ONEARG; ONEARG;
if (what->aux != v1.type) if (what->aux != v1.type)
runtime( "Attempt to set static attribute to incompatible type" ); runtime( "Attempt to set static attribute to incompatible type" );
@ -877,6 +879,7 @@ interpret(struct f_inst *what)
} }
break; break;
case P('e','a'): /* Access to extended attributes */ case P('e','a'): /* Access to extended attributes */
ACCESS_RTE;
{ {
eattr *e = NULL; eattr *e = NULL;
if (!(f_flags & FF_FORCE_TMPATTR)) if (!(f_flags & FF_FORCE_TMPATTR))
@ -944,6 +947,7 @@ interpret(struct f_inst *what)
} }
break; break;
case P('e','S'): case P('e','S'):
ACCESS_RTE;
ONEARG; ONEARG;
{ {
struct ea_list *l = lp_alloc(f_pool, sizeof(struct ea_list) + sizeof(eattr)); struct ea_list *l = lp_alloc(f_pool, sizeof(struct ea_list) + sizeof(eattr));
@ -1021,10 +1025,12 @@ interpret(struct f_inst *what)
} }
break; break;
case 'P': case 'P':
ACCESS_RTE;
res.type = T_INT; res.type = T_INT;
res.val.i = (*f_rte)->pref; res.val.i = (*f_rte)->pref;
break; break;
case P('P','S'): case P('P','S'):
ACCESS_RTE;
ONEARG; ONEARG;
if (v1.type != T_INT) if (v1.type != T_INT)
runtime( "Can't set preference to non-integer" ); runtime( "Can't set preference to non-integer" );
@ -1246,6 +1252,7 @@ interpret(struct f_inst *what)
} }
else else
{ {
ACCESS_RTE;
v1.val.px.ip = (*f_rte)->net->n.prefix; v1.val.px.ip = (*f_rte)->net->n.prefix;
v1.val.px.len = (*f_rte)->net->n.pxlen; v1.val.px.len = (*f_rte)->net->n.pxlen;
@ -1478,22 +1485,27 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc
return res.val.i; return res.val.i;
} }
struct f_val
f_eval(struct f_inst *expr, struct linpool *tmp_pool)
{
f_flags = 0;
f_tmp_attrs = NULL;
f_rte = NULL;
f_pool = tmp_pool;
log_reset();
return interpret(expr);
}
int int
f_eval_int(struct f_inst *expr) f_eval_int(struct f_inst *expr)
{ {
/* Called independently in parse-time to eval expressions */ /* Called independently in parse-time to eval expressions */
struct f_val res; struct f_val res = f_eval(expr, cfg_mem);
f_flags = 0;
f_tmp_attrs = NULL;
f_rte = NULL;
f_pool = cfg_mem;
log_reset();
res = interpret(expr);
if (res.type != T_INT) if (res.type != T_INT)
cf_error("Integer expression expected"); cf_error("Integer expression expected");
return res.val.i; return res.val.i;
} }

View File

@ -109,6 +109,7 @@ struct ea_list;
struct rte; struct rte;
int f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags); int f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags);
struct f_val f_eval(struct f_inst *expr, struct linpool *tmp_pool);
int f_eval_int(struct f_inst *expr); int f_eval_int(struct f_inst *expr);
u32 f_eval_asn(struct f_inst *expr); u32 f_eval_asn(struct f_inst *expr);
@ -120,6 +121,8 @@ int i_same(struct f_inst *f1, struct f_inst *f2);
int val_compare(struct f_val v1, struct f_val v2); int val_compare(struct f_val v1, struct f_val v2);
int tree_compare(const void *p1, const void *p2); int tree_compare(const void *p1, const void *p2);
void val_print(struct f_val v);
#define F_NOP 0 #define F_NOP 0
#define F_NONL 1 #define F_NONL 1
#define F_ACCEPT 2 /* Need to preserve ordering: accepts < rejects! */ #define F_ACCEPT 2 /* Need to preserve ordering: accepts < rejects! */

View File

@ -13,6 +13,7 @@
#include "nest/cmds.h" #include "nest/cmds.h"
#include "lib/string.h" #include "lib/string.h"
#include "lib/resource.h" #include "lib/resource.h"
#include "filter/filter.h"
extern int shutting_down; extern int shutting_down;
extern int configuring; extern int configuring;
@ -90,3 +91,22 @@ cmd_show_memory(void)
print_size("Total:", rmemsize(&root_pool)); print_size("Total:", rmemsize(&root_pool));
cli_msg(0, ""); cli_msg(0, "");
} }
extern const char *log_buffer_ptr;
void
cmd_eval(struct f_inst *expr)
{
struct f_val v = f_eval(expr, this_cli->parser_pool);
log_reset();
if (v.type == T_RETURN)
{
cli_msg(8008, "runtime error");
return;
}
val_print(v);
cli_msg(23, "%s", log_buffer_ptr);
log_reset();
}

View File

@ -11,6 +11,9 @@ struct sym_show_data {
struct symbol *sym; struct symbol *sym;
}; };
struct f_inst;
void cmd_show_status(void); void cmd_show_status(void);
void cmd_show_symbols(struct sym_show_data *sym); void cmd_show_symbols(struct sym_show_data *sym);
void cmd_show_memory(void); void cmd_show_memory(void);
void cmd_eval(struct f_inst *expr);

View File

@ -619,7 +619,11 @@ CF_CLI(DUMP ROUTES,,, [[Dump routing table]])
CF_CLI(DUMP PROTOCOLS,,, [[Dump protocol information]]) CF_CLI(DUMP PROTOCOLS,,, [[Dump protocol information]])
{ protos_dump_all(); cli_msg(0, ""); } ; { protos_dump_all(); cli_msg(0, ""); } ;
CF_CLI(ECHO, echo_mask echo_size, [all | off | <mask>] [<buffer-size>], [[Configure echoing of log messages]]) { CF_CLI(EVAL, term, <expr>, [[Evaluate an expression]])
{ cmd_eval($2); } ;
CF_CLI_HELP(ECHO, ..., [[Control echoing of log messages]])
CF_CLI(ECHO, echo_mask echo_size, (all | off | { debug | trace | info | remote | warning | error | auth }) [<buffer-size>], [[Control echoing of log messages]]) {
cli_set_log_echo(this_cli, $2, $3); cli_set_log_echo(this_cli, $2, $3);
cli_msg(0, ""); cli_msg(0, "");
} ; } ;
@ -627,7 +631,7 @@ CF_CLI(ECHO, echo_mask echo_size, [all | off | <mask>] [<buffer-size>], [[Config
echo_mask: echo_mask:
ALL { $$ = ~0; } ALL { $$ = ~0; }
| OFF { $$ = 0; } | OFF { $$ = 0; }
| NUM | '{' log_mask_list '}' { $$ = $2; }
; ;
echo_size: echo_size:

View File

@ -254,6 +254,8 @@ void bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsi
#define BS_ESTABLISHED 5 #define BS_ESTABLISHED 5
#define BS_CLOSE 6 /* Used during transition to BS_IDLE */ #define BS_CLOSE 6 /* Used during transition to BS_IDLE */
#define BS_MAX 7
/* BGP start states /* BGP start states
* *
* Used in PS_START for fine-grained specification of starting state. * Used in PS_START for fine-grained specification of starting state.

View File

@ -24,6 +24,13 @@
static struct rate_limit rl_rcv_update, rl_snd_update; static struct rate_limit rl_rcv_update, rl_snd_update;
/* Table for state -> RFC 6608 FSM error subcodes */
static byte fsm_err_subcode[BS_MAX] = {
[BS_OPENSENT] = 1,
[BS_OPENCONFIRM] = 2,
[BS_ESTABLISHED] = 3
};
/* /*
* MRT Dump format is not semantically specified. * MRT Dump format is not semantically specified.
* We will use these values in appropriate fields: * We will use these values in appropriate fields:
@ -720,7 +727,7 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, int len)
/* Check state */ /* Check state */
if (conn->state != BS_OPENSENT) if (conn->state != BS_OPENSENT)
{ bgp_error(conn, 5, 0, NULL, 0); return; } { bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0); return; }
/* Check message contents */ /* Check message contents */
if (len < 29 || len != 29 + pkt[28]) if (len < 29 || len != 29 + pkt[28])
@ -1060,7 +1067,7 @@ bgp_rx_update(struct bgp_conn *conn, byte *pkt, int len)
bgp_conn_enter_established_state(conn); bgp_conn_enter_established_state(conn);
if (conn->state != BS_ESTABLISHED) if (conn->state != BS_ESTABLISHED)
{ bgp_error(conn, 5, 0, NULL, 0); return; } { bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0); return; }
bgp_start_timer(conn->hold_timer, conn->hold_time); bgp_start_timer(conn->hold_timer, conn->hold_time);
/* Find parts of the packet and check sizes */ /* Find parts of the packet and check sizes */
@ -1122,7 +1129,10 @@ static struct {
{ 3, 10, "Invalid network field" }, { 3, 10, "Invalid network field" },
{ 3, 11, "Malformed AS_PATH" }, { 3, 11, "Malformed AS_PATH" },
{ 4, 0, "Hold timer expired" }, { 4, 0, "Hold timer expired" },
{ 5, 0, "Finite state machine error" }, { 5, 0, "Finite state machine error" }, /* Subcodes are according to [RFC6608] */
{ 5, 1, "Unexpected message in OpenSent state" },
{ 5, 2, "Unexpected message in OpenConfirm state" },
{ 5, 3, "Unexpected message in Established state" },
{ 6, 0, "Cease" }, /* Subcodes are according to [RFC4486] */ { 6, 0, "Cease" }, /* Subcodes are according to [RFC4486] */
{ 6, 1, "Maximum number of prefixes reached" }, { 6, 1, "Maximum number of prefixes reached" },
{ 6, 2, "Administrative shutdown" }, { 6, 2, "Administrative shutdown" },
@ -1253,7 +1263,7 @@ bgp_rx_keepalive(struct bgp_conn *conn)
case BS_ESTABLISHED: case BS_ESTABLISHED:
break; break;
default: default:
bgp_error(conn, 5, 0, NULL, 0); bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0);
} }
} }
@ -1265,7 +1275,7 @@ bgp_rx_route_refresh(struct bgp_conn *conn, byte *pkt, int len)
BGP_TRACE(D_PACKETS, "Got ROUTE-REFRESH"); BGP_TRACE(D_PACKETS, "Got ROUTE-REFRESH");
if (conn->state != BS_ESTABLISHED) if (conn->state != BS_ESTABLISHED)
{ bgp_error(conn, 5, 0, NULL, 0); return; } { bgp_error(conn, 5, fsm_err_subcode[conn->state], NULL, 0); return; }
if (!p->cf->enable_refresh) if (!p->cf->enable_refresh)
{ bgp_error(conn, 1, 3, pkt+18, 1); return; } { bgp_error(conn, 1, 3, pkt+18, 1); return; }

View File

@ -70,6 +70,8 @@ static char log_buffer[LOG_BUFFER_SIZE];
static char *log_buffer_pos; static char *log_buffer_pos;
static int log_buffer_remains; static int log_buffer_remains;
const char *log_buffer_ptr = log_buffer;
/** /**
* log_reset - reset the log buffer * log_reset - reset the log buffer