0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2025-01-03 15:41:54 +00:00

Merge branch 'int-new' into bash-completion

This commit is contained in:
Jan Moskyto Matejka 2017-07-12 13:47:32 +02:00
commit a109ef6b71
23 changed files with 217 additions and 215 deletions

View File

@ -44,6 +44,8 @@ struct cmd_node {
static struct cmd_node cmd_root; static struct cmd_node cmd_root;
#define isspace_(X) isspace((unsigned char) (X))
void void
cmd_build_tree(void) cmd_build_tree(void)
{ {
@ -61,7 +63,7 @@ cmd_build_tree(void)
while (*c) while (*c)
{ {
char *d = c; char *d = c;
while (*c && !isspace(*c)) while (*c && !isspace_(*c))
c++; c++;
for(new=old->son; new; new=new->sibling) for(new=old->son; new; new=new->sibling)
if (new->len == c-d && !memcmp(new->token, d, c-d)) if (new->len == c-d && !memcmp(new->token, d, c-d))
@ -79,7 +81,7 @@ cmd_build_tree(void)
new->prio = (new->len == 3 && (!memcmp(new->token, "roa", 3) || !memcmp(new->token, "rip", 3))) ? 0 : 1; /* Hack */ new->prio = (new->len == 3 && (!memcmp(new->token, "roa", 3) || !memcmp(new->token, "rip", 3))) ? 0 : 1; /* Hack */
} }
old = new; old = new;
while (isspace(*c)) while (isspace_(*c))
c++; c++;
} }
if (cmd->is_real_cmd) if (cmd->is_real_cmd)
@ -170,13 +172,13 @@ cmd_help(const char *cmd, int len)
n = &cmd_root; n = &cmd_root;
while (cmd < end) while (cmd < end)
{ {
if (isspace(*cmd)) if (isspace_(*cmd))
{ {
cmd++; cmd++;
continue; continue;
} }
z = cmd; z = cmd;
while (cmd < end && !isspace(*cmd)) while (cmd < end && !isspace_(*cmd))
cmd++; cmd++;
m = cmd_find_abbrev(n, z, cmd-z, &ambig); m = cmd_find_abbrev(n, z, cmd-z, &ambig);
if (ambig) if (ambig)
@ -283,20 +285,20 @@ cmd_complete(const char *cmd, int len, char *buf, int again)
int ambig, cnt = 0, common; int ambig, cnt = 0, common;
/* Find the last word we want to complete */ /* Find the last word we want to complete */
for(fin=end; fin > start && !isspace(fin[-1]); fin--) for(fin=end; fin > start && !isspace_(fin[-1]); fin--)
; ;
/* Find the context */ /* Find the context */
n = &cmd_root; n = &cmd_root;
while (cmd < fin) while (cmd < fin)
{ {
if (isspace(*cmd)) if (isspace_(*cmd))
{ {
cmd++; cmd++;
continue; continue;
} }
z = cmd; z = cmd;
while (cmd < fin && !isspace(*cmd)) while (cmd < fin && !isspace_(*cmd))
cmd++; cmd++;
m = cmd_find_abbrev(n, z, cmd-z, &ambig); m = cmd_find_abbrev(n, z, cmd-z, &ambig);
if (ambig) if (ambig)
@ -382,13 +384,13 @@ cmd_expand(char *cmd)
n = &cmd_root; n = &cmd_root;
while (*c) while (*c)
{ {
if (isspace(*c)) if (isspace_(*c))
{ {
c++; c++;
continue; continue;
} }
b = c; b = c;
while (*c && !isspace(*c)) while (*c && !isspace_(*c))
c++; c++;
m = cmd_find_abbrev(n, b, c-b, &ambig); m = cmd_find_abbrev(n, b, c-b, &ambig);
if (!m) if (!m)

View File

@ -48,6 +48,7 @@
#include "conf/conf.h" #include "conf/conf.h"
#include "conf/cf-parse.tab.h" #include "conf/cf-parse.tab.h"
#include "lib/string.h" #include "lib/string.h"
#include "lib/hash.h"
struct keyword { struct keyword {
byte *name; byte *name;
@ -57,22 +58,37 @@ struct keyword {
#include "conf/keywords.h" #include "conf/keywords.h"
#define KW_HASH_SIZE 64 /* Could be defined by Bison in cf-parse.tab.h, inteferes with SYM hash */
static struct keyword *kw_hash[KW_HASH_SIZE]; #ifdef SYM
static int kw_hash_inited; #undef SYM
#endif
static uint cf_hash(byte *c);
#define KW_KEY(n) n->name
#define KW_NEXT(n) n->next
#define KW_EQ(a,b) !strcmp(a,b)
#define KW_FN(k) cf_hash(k)
#define KW_ORDER 8 /* Fixed */
#define SYM_KEY(n) n->name, n->scope->active
#define SYM_NEXT(n) n->next
#define SYM_EQ(a,s1,b,s2) !strcmp(a,b) && s1 == s2
#define SYM_FN(k,s) cf_hash(k)
#define SYM_ORDER 6 /* Initial */
#define SYM_REHASH sym_rehash
#define SYM_PARAMS /8, *1, 2, 2, 6, 20
HASH_DEFINE_REHASH_FN(SYM, struct symbol)
HASH(struct keyword) kw_hash;
#define SYM_HASH_SIZE 128
struct sym_scope {
struct sym_scope *next; /* Next on scope stack */
struct symbol *name; /* Name of this scope */
int active; /* Currently entered */
};
static struct sym_scope *conf_this_scope; static struct sym_scope *conf_this_scope;
static int cf_hash(byte *c);
static inline struct symbol * cf_get_sym(byte *c, uint h0);
linpool *cfg_mem; linpool *cfg_mem;
int (*cf_read_hook)(byte *buf, unsigned int max, int fd); int (*cf_read_hook)(byte *buf, unsigned int max, int fd);
@ -124,7 +140,8 @@ include ^{WHITE}*include{WHITE}*\".*\"{WHITE}*;
} }
{DIGIT}+:{DIGIT}+ { {DIGIT}+:{DIGIT}+ {
unsigned long int l, len1 UNUSED, len2; uint len1 UNUSED, len2;
u64 l;
char *e; char *e;
errno = 0; errno = 0;
@ -155,7 +172,8 @@ include ^{WHITE}*include{WHITE}*\".*\"{WHITE}*;
} }
[02]:{DIGIT}+:{DIGIT}+ { [02]:{DIGIT}+:{DIGIT}+ {
unsigned long int l, len1, len2; uint len1, len2;
u64 l;
char *e; char *e;
if (yytext[0] == '0') if (yytext[0] == '0')
@ -252,23 +270,20 @@ else: {
yytext[yyleng-1] = 0; yytext[yyleng-1] = 0;
yytext++; yytext++;
} }
unsigned int h = cf_hash(yytext);
struct keyword *k = kw_hash[h & (KW_HASH_SIZE-1)]; struct keyword *k = HASH_FIND(kw_hash, KW, yytext);
while (k) if (k)
{
if (k->value > 0)
return k->value;
else
{ {
if (!strcmp(k->name, yytext)) cf_lval.i = -k->value;
{ return ENUM;
if (k->value > 0)
return k->value;
else
{
cf_lval.i = -k->value;
return ENUM;
}
}
k=k->next;
} }
cf_lval.s = cf_get_sym(yytext, h); }
cf_lval.s = cf_get_symbol(yytext);
return SYM; return SYM;
} }
@ -331,13 +346,13 @@ else: {
%% %%
static int static uint
cf_hash(byte *c) cf_hash(byte *c)
{ {
unsigned int h = 13; uint h = 13 << 24;
while (*c) while (*c)
h = (h * 37) + *c++; h = h + (h >> 2) + (h >> 5) + ((uint) *c++ << 24);
return h; return h;
} }
@ -502,58 +517,29 @@ check_eof(void)
} }
static struct symbol * static struct symbol *
cf_new_sym(byte *c, uint h0) cf_new_symbol(byte *c)
{ {
uint h = h0 & (SYM_HASH_SIZE-1); struct symbol *s;
struct symbol *s, **ht;
int l;
if (!new_config->sym_hash) uint l = strlen(c);
new_config->sym_hash = cfg_allocz(SYM_HASH_SIZE * sizeof(struct keyword *));
ht = new_config->sym_hash;
l = strlen(c);
if (l > SYM_MAX_LEN) if (l > SYM_MAX_LEN)
cf_error("Symbol too long"); cf_error("Symbol too long");
s = cfg_alloc(sizeof(struct symbol) + l); s = cfg_alloc(sizeof(struct symbol) + l);
s->next = ht[h];
ht[h] = s;
s->scope = conf_this_scope; s->scope = conf_this_scope;
s->class = SYM_VOID; s->class = SYM_VOID;
s->def = NULL; s->def = NULL;
s->aux = 0; s->aux = 0;
strcpy(s->name, c); strcpy(s->name, c);
if (!new_config->sym_hash.data)
HASH_INIT(new_config->sym_hash, new_config->pool, SYM_ORDER);
HASH_INSERT2(new_config->sym_hash, SYM, new_config->pool, s);
return s; return s;
} }
static struct symbol *
cf_find_sym(struct config *cfg, byte *c, uint h0)
{
uint h = h0 & (SYM_HASH_SIZE-1);
struct symbol *s, **ht;
if (ht = cfg->sym_hash)
{
for(s = ht[h]; s; s=s->next)
if (!strcmp(s->name, c) && s->scope->active)
return s;
}
if (ht = cfg->sym_fallback)
{
/* We know only top-level scope is active */
for(s = ht[h]; s; s=s->next)
if (!strcmp(s->name, c) && s->scope->active)
return s;
}
return NULL;
}
static inline struct symbol *
cf_get_sym(byte *c, uint h0)
{
return cf_find_sym(new_config, c, h0) ?: cf_new_sym(c, h0);
}
/** /**
* cf_find_symbol - find a symbol by name * cf_find_symbol - find a symbol by name
* @cfg: specificed config * @cfg: specificed config
@ -568,7 +554,18 @@ cf_get_sym(byte *c, uint h0)
struct symbol * struct symbol *
cf_find_symbol(struct config *cfg, byte *c) cf_find_symbol(struct config *cfg, byte *c)
{ {
return cf_find_sym(cfg, c, cf_hash(c)); struct symbol *s;
if (cfg->sym_hash.data &&
(s = HASH_FIND(cfg->sym_hash, SYM, c, 1)))
return s;
if (cfg->fallback &&
cfg->fallback->sym_hash.data &&
(s = HASH_FIND(cfg->fallback->sym_hash, SYM, c, 1)))
return s;
return NULL;
} }
/** /**
@ -583,7 +580,7 @@ cf_find_symbol(struct config *cfg, byte *c)
struct symbol * struct symbol *
cf_get_symbol(byte *c) cf_get_symbol(byte *c)
{ {
return cf_get_sym(c, cf_hash(c)); return cf_find_symbol(new_config, c) ?: cf_new_symbol(c);
} }
struct symbol * struct symbol *
@ -596,7 +593,7 @@ cf_default_name(char *template, int *counter)
for(;;) for(;;)
{ {
bsprintf(buf, template, ++(*counter)); bsprintf(buf, template, ++(*counter));
s = cf_get_sym(buf, cf_hash(buf)); s = cf_get_symbol(buf);
if (s->class == SYM_VOID) if (s->class == SYM_VOID)
return s; return s;
if (!perc) if (!perc)
@ -627,7 +624,7 @@ cf_define_symbol(struct symbol *sym, int type, void *def)
{ {
if (sym->scope == conf_this_scope) if (sym->scope == conf_this_scope)
cf_error("Symbol already defined"); cf_error("Symbol already defined");
sym = cf_new_sym(sym->name, cf_hash(sym->name)); sym = cf_new_symbol(sym->name);
} }
sym->class = type; sym->class = type;
sym->def = def; sym->def = def;
@ -637,15 +634,11 @@ cf_define_symbol(struct symbol *sym, int type, void *def)
static void static void
cf_lex_init_kh(void) cf_lex_init_kh(void)
{ {
struct keyword *k; HASH_INIT(kw_hash, &root_pool, KW_ORDER);
for(k=keyword_list; k->name; k++) struct keyword *k;
{ for (k=keyword_list; k->name; k++)
unsigned h = cf_hash(k->name) & (KW_HASH_SIZE-1); HASH_INSERT(kw_hash, KW, k);
k->next = kw_hash[h];
kw_hash[h] = k;
}
kw_hash_inited = 1;
} }
/** /**
@ -659,7 +652,7 @@ cf_lex_init_kh(void)
void void
cf_lex_init(int is_cli, struct config *c) cf_lex_init(int is_cli, struct config *c)
{ {
if (!kw_hash_inited) if (!kw_hash.data)
cf_lex_init_kh(); cf_lex_init_kh();
ifs_head = ifs = push_ifs(NULL); ifs_head = ifs = push_ifs(NULL);
@ -718,24 +711,6 @@ cf_pop_scope(void)
ASSERT(conf_this_scope); ASSERT(conf_this_scope);
} }
struct symbol *
cf_walk_symbols(struct config *cf, struct symbol *sym, int *pos)
{
for(;;)
{
if (!sym)
{
if (*pos >= SYM_HASH_SIZE)
return NULL;
sym = cf->sym_hash[(*pos)++];
}
else
sym = sym->next;
if (sym && sym->scope->active)
return sym;
}
}
/** /**
* cf_symbol_class_name - get name of a symbol class * cf_symbol_class_name - get name of a symbol class
* @sym: symbol * @sym: symbol

View File

@ -166,7 +166,7 @@ int
cli_parse(struct config *c) cli_parse(struct config *c)
{ {
int done = 0; int done = 0;
c->sym_fallback = config->sym_hash; c->fallback = config;
new_config = c; new_config = c;
cfg_mem = c->mem; cfg_mem = c->mem;
if (setjmp(conf_jmpbuf)) if (setjmp(conf_jmpbuf))
@ -177,7 +177,7 @@ cli_parse(struct config *c)
done = 1; done = 1;
cleanup: cleanup:
c->sym_fallback = NULL; c->fallback = NULL;
new_config = NULL; new_config = NULL;
cfg_mem = NULL; cfg_mem = NULL;
return done; return done;

View File

@ -11,6 +11,7 @@
#include "sysdep/config.h" #include "sysdep/config.h"
#include "lib/ip.h" #include "lib/ip.h"
#include "lib/hash.h"
#include "lib/resource.h" #include "lib/resource.h"
#include "sysdep/unix/timer.h" #include "sysdep/unix/timer.h"
@ -52,8 +53,8 @@ struct config {
char *err_file_name; /* File name containing error */ char *err_file_name; /* File name containing error */
char *file_name; /* Name of main configuration file */ char *file_name; /* Name of main configuration file */
int file_fd; /* File descriptor of main configuration file */ int file_fd; /* File descriptor of main configuration file */
struct symbol **sym_hash; /* Lexer: symbol hash table */ HASH(struct symbol) sym_hash; /* Lexer: symbol hash table */
struct symbol **sym_fallback; /* Lexer: fallback symbol hash table */ struct config *fallback; /* Link to regular config for CLI parsing */
int obstacle_count; /* Number of items blocking freeing of this config */ int obstacle_count; /* Number of items blocking freeing of this config */
int shutdown; /* This is a pseudo-config for daemon shutdown */ int shutdown; /* This is a pseudo-config for daemon shutdown */
bird_clock_t load_time; /* When we've got this configuration */ bird_clock_t load_time; /* When we've got this configuration */
@ -114,6 +115,12 @@ struct symbol {
char name[1]; char name[1];
}; };
struct sym_scope {
struct sym_scope *next; /* Next on scope stack */
struct symbol *name; /* Name of this scope */
int active; /* Currently entered */
};
#define SYM_MAX_LEN 64 #define SYM_MAX_LEN 64
/* Remember to update cf_symbol_class_name() */ /* Remember to update cf_symbol_class_name() */
@ -155,7 +162,6 @@ struct symbol *cf_default_name(char *template, int *counter);
struct symbol *cf_define_symbol(struct symbol *symbol, int type, void *def); struct symbol *cf_define_symbol(struct symbol *symbol, int type, void *def);
void cf_push_scope(struct symbol *); void cf_push_scope(struct symbol *);
void cf_pop_scope(void); void cf_pop_scope(void);
struct symbol *cf_walk_symbols(struct config *cf, struct symbol *sym, int *pos);
char *cf_symbol_class_name(struct symbol *sym); char *cf_symbol_class_name(struct symbol *sym);
static inline int cf_symbol_is_constant(struct symbol *sym) static inline int cf_symbol_is_constant(struct symbol *sym)

View File

@ -27,16 +27,16 @@ CF_HDR
CF_DEFINES CF_DEFINES
static void static void
check_u16(unsigned val) check_u16(uint val)
{ {
if (val > 0xFFFF) if (val > 0xFFFF)
cf_error("Value %d out of range (0-65535)", val); cf_error("Value %u out of range (0-65535)", val);
} }
CF_DECLS CF_DECLS
%union { %union {
int i; uint i;
u32 i32; u32 i32;
u64 i64; u64 i64;
ip_addr a; ip_addr a;
@ -175,7 +175,7 @@ ipa_scope:
pxlen4: pxlen4:
'/' NUM { '/' NUM {
if ($2 < 0 || $2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %d", $2); if ($2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %u", $2);
$$ = $2; $$ = $2;
} }
| ':' IP4 { | ':' IP4 {
@ -187,17 +187,24 @@ pxlen4:
net_ip4_: IP4 pxlen4 net_ip4_: IP4 pxlen4
{ {
net_fill_ip4(&($$), $1, $2); net_fill_ip4(&($$), $1, $2);
if (!net_validate_ip4((net_addr_ip4 *) &($$)))
cf_error("Invalid IPv4 prefix"); net_addr_ip4 *n = (void *) &($$);
if (!net_validate_ip4(n))
cf_error("Invalid IPv4 prefix %I4/%d, maybe you wanted %I4/%d",
n->prefix, n->pxlen, ip4_and(n->prefix, ip4_mkmask(n->pxlen)), n->pxlen);
}; };
net_ip6_: IP6 '/' NUM net_ip6_: IP6 '/' NUM
{ {
if ($3 > IP6_MAX_PREFIX_LENGTH)
cf_error("Invalid prefix length %u", $3);
net_fill_ip6(&($$), $1, $3); net_fill_ip6(&($$), $1, $3);
if ($3 < 0 || $3 > IP6_MAX_PREFIX_LENGTH)
cf_error("Invalid prefix length %d", $3); net_addr_ip6 *n = (void *) &($$);
if (!net_validate_ip6((net_addr_ip6 *) &($$))) if (!net_validate_ip6(n))
cf_error("Invalid IPv6 prefix"); cf_error("Invalid IPv6 prefix %I6/%d, maybe you wanted %I6/%d",
n->prefix, n->pxlen, ip6_and(n->prefix, ip6_mkmask(n->pxlen)), n->pxlen);
}; };
net_vpn4_: VPN_RD net_ip4_ net_vpn4_: VPN_RD net_ip4_
@ -216,16 +223,16 @@ net_roa4_: net_ip4_ MAX NUM AS NUM
{ {
$$ = cfg_alloc(sizeof(net_addr_roa4)); $$ = cfg_alloc(sizeof(net_addr_roa4));
net_fill_roa4($$, net4_prefix(&$1), net4_pxlen(&$1), $3, $5); net_fill_roa4($$, net4_prefix(&$1), net4_pxlen(&$1), $3, $5);
if ($3 < (int) net4_pxlen(&$1) || $3 > IP4_MAX_PREFIX_LENGTH) if ($3 < net4_pxlen(&$1) || $3 > IP4_MAX_PREFIX_LENGTH)
cf_error("Invalid max prefix length %d", $3); cf_error("Invalid max prefix length %u", $3);
}; };
net_roa6_: net_ip6_ MAX NUM AS NUM net_roa6_: net_ip6_ MAX NUM AS NUM
{ {
$$ = cfg_alloc(sizeof(net_addr_roa6)); $$ = cfg_alloc(sizeof(net_addr_roa6));
net_fill_roa6($$, net6_prefix(&$1), net6_pxlen(&$1), $3, $5); net_fill_roa6($$, net6_prefix(&$1), net6_pxlen(&$1), $3, $5);
if ($3 < (int) net6_pxlen(&$1) || $3 > IP6_MAX_PREFIX_LENGTH) if ($3 < net6_pxlen(&$1) || $3 > IP6_MAX_PREFIX_LENGTH)
cf_error("Invalid max prefix length %d", $3); cf_error("Invalid max prefix length %u", $3);
}; };
net_ip_: net_ip4_ | net_ip6_ ; net_ip_: net_ip4_ | net_ip6_ ;

View File

@ -44,19 +44,19 @@ CF_GRAMMAR
/* Network Flow Specification */ /* Network Flow Specification */
flow_num_op: flow_num_op:
TRUE { $$ = 0b000; } TRUE { $$ = FLOW_OP_TRUE; }
| '=' { $$ = 0b001; } | '=' { $$ = FLOW_OP_EQ; }
| NEQ { $$ = 0b110; } | NEQ { $$ = FLOW_OP_NEQ; }
| '<' { $$ = 0b100; } | '<' { $$ = FLOW_OP_LT; }
| LEQ { $$ = 0b101; } | LEQ { $$ = FLOW_OP_LEQ; }
| '>' { $$ = 0b010; } | '>' { $$ = FLOW_OP_GT; }
| GEQ { $$ = 0b011; } | GEQ { $$ = FLOW_OP_GEQ; }
| FALSE { $$ = 0b111; } | FALSE { $$ = FLOW_OP_FALSE; }
; ;
flow_logic_op: flow_logic_op:
OR { $$ = 0x00; } OR { $$ = FLOW_OP_OR; }
| AND { $$ = 0x40; } | AND { $$ = FLOW_OP_AND; }
; ;
flow_num_type_: flow_num_type_:
@ -97,13 +97,13 @@ flow_num_opts:
flow_num_opt_ext_expr: flow_num_opt_ext_expr:
expr { expr {
flow_check_cf_value_length(this_flow, $1); flow_check_cf_value_length(this_flow, $1);
flow_builder_add_op_val(this_flow, 0b001, $1); flow_builder_add_op_val(this_flow, FLOW_OP_EQ, $1);
} }
| expr DDOT expr { | expr DDOT expr {
flow_check_cf_value_length(this_flow, $1); flow_check_cf_value_length(this_flow, $1);
flow_check_cf_value_length(this_flow, $3); flow_check_cf_value_length(this_flow, $3);
flow_builder_add_op_val(this_flow, 0b011, $1); /* >= */ flow_builder_add_op_val(this_flow, FLOW_OP_GEQ, $1);
flow_builder_add_op_val(this_flow, 0x40 | 0b101, $3); /* AND <= */ flow_builder_add_op_val(this_flow, FLOW_OP_AND | FLOW_OP_LEQ, $3);
} }
; ;

View File

@ -728,8 +728,8 @@ fprefix:
| net_ip_ '-' { $$.net = $1; $$.lo = 0; $$.hi = $1.pxlen; } | net_ip_ '-' { $$.net = $1; $$.lo = 0; $$.hi = $1.pxlen; }
| net_ip_ '{' NUM ',' NUM '}' { | net_ip_ '{' NUM ',' NUM '}' {
$$.net = $1; $$.lo = $3; $$.hi = $5; $$.net = $1; $$.lo = $3; $$.hi = $5;
if ((0 > $3) || ($3 > $5) || ($5 > net_max_prefix_length[$1.type])) if (($3 > $5) || ($5 > net_max_prefix_length[$1.type]))
cf_error("Invalid prefix pattern range: {%d, %d}", $3, $5); cf_error("Invalid prefix pattern range: {%u, %u}", $3, $5);
} }
; ;

View File

@ -19,11 +19,11 @@ struct f_inst { /* Instruction */
u16 code; /* Instruction code, see the interpret() function and P() macro */ u16 code; /* Instruction code, see the interpret() function and P() macro */
u16 aux; /* Extension to instruction code, T_*, EA_*, EAF_* */ u16 aux; /* Extension to instruction code, T_*, EA_*, EAF_* */
union { union {
int i; uint i;
void *p; void *p;
} a1; /* The first argument */ } a1; /* The first argument */
union { union {
int i; uint i;
void *p; void *p;
} a2; /* The second argument */ } a2; /* The second argument */
int lineno; int lineno;

View File

@ -754,7 +754,7 @@ flow_builder_add_val_mask(struct flow_builder *fb, byte op, u32 value, u32 mask)
if (a) if (a)
{ {
flow_builder_add_op_val(fb, op ^ 0x01, a); flow_builder_add_op_val(fb, op ^ 0x01, a);
op |= 0x40; op |= FLOW_OP_AND;
} }
if (b) if (b)
@ -897,34 +897,26 @@ flow_builder_clear(struct flow_builder *fb)
*/ */
/* Flowspec operators for [op, value]+ pairs */ /* Flowspec operators for [op, value]+ pairs */
#define FLOW_TRUE 0b000
#define FLOW_EQ 0b001
#define FLOW_GT 0b010
#define FLOW_GTE 0b011
#define FLOW_LT 0b100
#define FLOW_LTE 0b101
#define FLOW_NEQ 0b110
#define FLOW_FALSE 0b111
static const char * static const char *
num_op_str(const byte *op) num_op_str(const byte *op)
{ {
switch (*op & 0x07) switch (*op & 0x07)
{ {
case FLOW_TRUE: return "true"; case FLOW_OP_TRUE: return "true";
case FLOW_EQ: return "="; case FLOW_OP_EQ: return "=";
case FLOW_GT: return ">"; case FLOW_OP_GT: return ">";
case FLOW_GTE: return ">="; case FLOW_OP_GEQ: return ">=";
case FLOW_LT: return "<"; case FLOW_OP_LT: return "<";
case FLOW_LTE: return "<="; case FLOW_OP_LEQ: return "<=";
case FLOW_NEQ: return "!="; case FLOW_OP_NEQ: return "!=";
case FLOW_FALSE: return "false"; case FLOW_OP_FALSE: return "false";
} }
return NULL; return NULL;
} }
static u64 static uint
get_value(const byte *val, u8 len) get_value(const byte *val, u8 len)
{ {
switch (len) switch (len)
@ -932,7 +924,8 @@ get_value(const byte *val, u8 len)
case 1: return *val; case 1: return *val;
case 2: return get_u16(val); case 2: return get_u16(val);
case 4: return get_u32(val); case 4: return get_u32(val);
case 8: return get_u64(val); // No component may have length 8
// case 8: return get_u64(val);
} }
return 0; return 0;
@ -974,7 +967,7 @@ net_format_flow_num(buffer *b, const byte *part)
{ {
const byte *last_op = NULL; const byte *last_op = NULL;
const byte *op = part+1; const byte *op = part+1;
u64 val; uint val;
uint len; uint len;
uint first = 1; uint first = 1;
@ -984,8 +977,8 @@ net_format_flow_num(buffer *b, const byte *part)
{ {
/* XXX: I don't like this so complicated if-tree */ /* XXX: I don't like this so complicated if-tree */
if (!isset_and(op) && if (!isset_and(op) &&
((num_op( op) == FLOW_EQ) || (num_op( op) == FLOW_GTE)) && ((num_op( op) == FLOW_OP_EQ) || (num_op( op) == FLOW_OP_GEQ)) &&
((num_op(last_op) == FLOW_EQ) || (num_op(last_op) == FLOW_LTE))) ((num_op(last_op) == FLOW_OP_EQ) || (num_op(last_op) == FLOW_OP_LEQ)))
{ {
b->pos--; /* Remove last char (it is a space) */ b->pos--; /* Remove last char (it is a space) */
buffer_puts(b, ","); buffer_puts(b, ",");
@ -1001,7 +994,7 @@ net_format_flow_num(buffer *b, const byte *part)
val = get_value(op+1, len); val = get_value(op+1, len);
if (!isset_end(op) && !isset_and(op) && isset_and(op+1+len) && if (!isset_end(op) && !isset_and(op) && isset_and(op+1+len) &&
(num_op(op) == FLOW_GTE) && (num_op(op+1+len) == FLOW_LTE)) (num_op(op) == FLOW_OP_GEQ) && (num_op(op+1+len) == FLOW_OP_LEQ))
{ {
/* Display interval */ /* Display interval */
buffer_print(b, "%u..", val); buffer_print(b, "%u..", val);
@ -1010,7 +1003,7 @@ net_format_flow_num(buffer *b, const byte *part)
val = get_value(op+1, len); val = get_value(op+1, len);
buffer_print(b, "%u", val); buffer_print(b, "%u", val);
} }
else if (num_op(op) == FLOW_EQ) else if (num_op(op) == FLOW_OP_EQ)
{ {
buffer_print(b, "%u", val); buffer_print(b, "%u", val);
} }
@ -1038,7 +1031,7 @@ static void
net_format_flow_bitmask(buffer *b, const byte *part) net_format_flow_bitmask(buffer *b, const byte *part)
{ {
const byte *op = part+1; const byte *op = part+1;
u64 val; uint val;
uint len; uint len;
uint first = 1; uint first = 1;

View File

@ -14,6 +14,20 @@
#include "lib/net.h" #include "lib/net.h"
/* Flow component operators */
#define FLOW_OP_TRUE 0x00 /* 0b000 */
#define FLOW_OP_EQ 0x01 /* 0b001 */
#define FLOW_OP_GT 0x02 /* 0b010 */
#define FLOW_OP_GEQ 0x03 /* 0b011 */
#define FLOW_OP_LT 0x04 /* 0b100 */
#define FLOW_OP_LEQ 0x05 /* 0b101 */
#define FLOW_OP_NEQ 0x06 /* 0b110 */
#define FLOW_OP_FALSE 0x07 /* 0b111 */
#define FLOW_OP_OR 0x00
#define FLOW_OP_AND 0x40
/* Types of components in flowspec */ /* Types of components in flowspec */
enum flow_type { enum flow_type {
FLOW_TYPE_DST_PREFIX = 1, FLOW_TYPE_DST_PREFIX = 1,

View File

@ -257,6 +257,7 @@ cli_command(struct cli *c)
log(L_TRACE "CLI: %s", c->rx_buf); log(L_TRACE "CLI: %s", c->rx_buf);
bzero(&f, sizeof(f)); bzero(&f, sizeof(f));
f.mem = c->parser_pool; f.mem = c->parser_pool;
f.pool = rp_new(c->pool, "Config");
cf_read_hook = cli_cmd_read_hook; cf_read_hook = cli_cmd_read_hook;
cli_rh_pos = c->rx_buf; cli_rh_pos = c->rx_buf;
cli_rh_len = strlen(c->rx_buf); cli_rh_len = strlen(c->rx_buf);
@ -266,6 +267,8 @@ cli_command(struct cli *c)
res = cli_parse(&f); res = cli_parse(&f);
if (!res) if (!res)
cli_printf(c, 9001, f.err_msg); cli_printf(c, 9001, f.err_msg);
config_free(&f);
} }
static void static void

View File

@ -48,22 +48,24 @@ cmd_show_status(void)
void void
cmd_show_symbols(struct sym_show_data *sd) cmd_show_symbols(struct sym_show_data *sd)
{ {
int pos = 0; if (sd->sym)
struct symbol *sym = sd->sym; cli_msg(1010, "%-8s\t%s", sd->sym->name, cf_symbol_class_name(sd->sym));
if (sym)
cli_msg(1010, "%-8s\t%s", sym->name, cf_symbol_class_name(sym));
else else
{
HASH_WALK(config->sym_hash, next, sym)
{ {
while (sym = cf_walk_symbols(config, sym, &pos)) if (!sym->scope->active)
{ continue;
if (sd->type && (sym->class != sd->type))
continue;
cli_msg(-1010, "%-8s\t%s", sym->name, cf_symbol_class_name(sym)); if (sd->type && (sym->class != sd->type))
} continue;
cli_msg(0, "");
cli_msg(-1010, "%-8s\t%s", sym->name, cf_symbol_class_name(sym));
} }
HASH_WALK_END;
cli_msg(0, "");
}
} }
static int static int

View File

@ -350,8 +350,8 @@ iface_patt:
; ;
tos: tos:
CLASS expr { $$ = $2 & 0xfc; if (($2 < 0) || ($2 > 255)) cf_error("TX class must be in range 0-255"); } CLASS expr { $$ = $2 & 0xfc; if ($2 > 255) cf_error("TX class must be in range 0-255"); }
| DSCP expr { $$ = ($2 & 0x3f) << 2; if (($2 < 0) || ($2 > 63)) cf_error("TX DSCP must be in range 0-63"); } | DSCP expr { $$ = ($2 & 0x3f) << 2; if ($2 > 63) cf_error("TX DSCP must be in range 0-63"); }
; ;
/* Direct device route protocol */ /* Direct device route protocol */

View File

@ -47,7 +47,7 @@ static void proto_shutdown_loop(struct timer *);
static void proto_rethink_goal(struct proto *p); static void proto_rethink_goal(struct proto *p);
static char *proto_state_name(struct proto *p); static char *proto_state_name(struct proto *p);
static void channel_verify_limits(struct channel *c); static void channel_verify_limits(struct channel *c);
static void channel_reset_limit(struct channel_limit *l); static inline void channel_reset_limit(struct channel_limit *l);
static inline int proto_is_done(struct proto *p) static inline int proto_is_done(struct proto *p)

View File

@ -248,7 +248,7 @@ bfd_check_authentication(struct bfd_proto *p, struct bfd_session *s, struct bfd_
/* BFD CSNs are in 32-bit circular number space */ /* BFD CSNs are in 32-bit circular number space */
u32 csn = ntohl(auth->csn); u32 csn = ntohl(auth->csn);
if (s->rx_csn_known && if (s->rx_csn_known &&
(((csn - s->rx_csn) > (3 * s->detect_mult)) || (((csn - s->rx_csn) > (3 * (uint) s->detect_mult)) ||
(meticulous && (csn == s->rx_csn)))) (meticulous && (csn == s->rx_csn))))
{ {
/* We want to report both new and old CSN */ /* We want to report both new and old CSN */

View File

@ -126,7 +126,7 @@ static inline void
ospf_check_defcost(int cost) ospf_check_defcost(int cost)
{ {
if ((cost <= 0) || (cost >= LSINFINITY)) if ((cost <= 0) || (cost >= LSINFINITY))
cf_error("Default cost must be in range 1-%d", LSINFINITY-1); cf_error("Default cost must be in range 1-%u", LSINFINITY-1);
} }
static inline void static inline void
@ -185,10 +185,10 @@ ospf_proto_item:
| RFC1583COMPAT bool { OSPF_CFG->rfc1583 = $2; } | RFC1583COMPAT bool { OSPF_CFG->rfc1583 = $2; }
| STUB ROUTER bool { OSPF_CFG->stub_router = $3; } | STUB ROUTER bool { OSPF_CFG->stub_router = $3; }
| ECMP bool { OSPF_CFG->ecmp = $2 ? OSPF_DEFAULT_ECMP_LIMIT : 0; } | ECMP bool { OSPF_CFG->ecmp = $2 ? OSPF_DEFAULT_ECMP_LIMIT : 0; }
| ECMP bool LIMIT expr { OSPF_CFG->ecmp = $2 ? $4 : 0; if ($4 < 0) cf_error("ECMP limit cannot be negative"); } | ECMP bool LIMIT expr { OSPF_CFG->ecmp = $2 ? $4 : 0; }
| MERGE EXTERNAL bool { OSPF_CFG->merge_external = $3; } | MERGE EXTERNAL bool { OSPF_CFG->merge_external = $3; }
| TICK expr { OSPF_CFG->tick = $2; if($2<=0) cf_error("Tick must be greater than zero"); } | TICK expr { OSPF_CFG->tick = $2; if($2 <= 0) cf_error("Tick must be greater than zero"); }
| INSTANCE ID expr { OSPF_CFG->instance_id = $3; if (($3<0) || ($3>255)) cf_error("Instance ID must be in range 0-255"); } | INSTANCE ID expr { OSPF_CFG->instance_id = $3; if ($3 > 255) cf_error("Instance ID must be in range 0-255"); }
| ospf_area | ospf_area
; ;
@ -318,7 +318,7 @@ ospf_iface_item:
| REAL BROADCAST bool { OSPF_PATT->real_bcast = $3; if (!ospf_cfg_is_v2()) cf_error("Real broadcast option requires OSPFv2"); } | REAL BROADCAST bool { OSPF_PATT->real_bcast = $3; if (!ospf_cfg_is_v2()) cf_error("Real broadcast option requires OSPFv2"); }
| PTP NETMASK bool { OSPF_PATT->ptp_netmask = $3; if (!ospf_cfg_is_v2()) cf_error("PtP netmask option requires OSPFv2"); } | PTP NETMASK bool { OSPF_PATT->ptp_netmask = $3; if (!ospf_cfg_is_v2()) cf_error("PtP netmask option requires OSPFv2"); }
| TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if (($3<=0) || ($3>65535)) cf_error("Transmit delay must be in range 1-65535"); } | TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if (($3<=0) || ($3>65535)) cf_error("Transmit delay must be in range 1-65535"); }
| PRIORITY expr { OSPF_PATT->priority = $2 ; if (($2<0) || ($2>255)) cf_error("Priority must be in range 0-255"); } | PRIORITY expr { OSPF_PATT->priority = $2 ; if ($2>255) cf_error("Priority must be in range 0-255"); }
| STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; } | STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; }
| STUB bool { OSPF_PATT->stub = $2 ; } | STUB bool { OSPF_PATT->stub = $2 ; }
| CHECK LINK bool { OSPF_PATT->check_link = $3; } | CHECK LINK bool { OSPF_PATT->check_link = $3; }
@ -404,7 +404,7 @@ ospf_iface_start:
ospf_instance_id: ospf_instance_id:
/* empty */ /* empty */
| INSTANCE expr { OSPF_PATT->instance_id = $2; if (($2<0) || ($2>255)) cf_error("Instance ID must be in range 0-255"); } | INSTANCE expr { OSPF_PATT->instance_id = $2; if ($2 > 255) cf_error("Instance ID must be in range 0-255"); }
; ;
ospf_iface_patt_list: ospf_iface_patt_list:

View File

@ -91,14 +91,14 @@ radv_iface_item:
| MIN DELAY expr { RADV_IFACE->min_delay = $3; if ($3 <= 0) cf_error("Min delay must be positive"); } | MIN DELAY expr { RADV_IFACE->min_delay = $3; if ($3 <= 0) cf_error("Min delay must be positive"); }
| MANAGED bool { RADV_IFACE->managed = $2; } | MANAGED bool { RADV_IFACE->managed = $2; }
| OTHER CONFIG bool { RADV_IFACE->other_config = $3; } | OTHER CONFIG bool { RADV_IFACE->other_config = $3; }
| LINK MTU expr { RADV_IFACE->link_mtu = $3; if ($3 < 0) cf_error("Link MTU must be 0 or positive"); } | LINK MTU expr { RADV_IFACE->link_mtu = $3; }
| REACHABLE TIME expr { RADV_IFACE->reachable_time = $3; if (($3 < 0) || ($3 > 3600000)) cf_error("Reachable time must be in range 0-3600000"); } | REACHABLE TIME expr { RADV_IFACE->reachable_time = $3; if ($3 > 3600000) cf_error("Reachable time must be in range 0-3600000"); }
| RETRANS TIMER expr { RADV_IFACE->retrans_timer = $3; if ($3 < 0) cf_error("Retrans timer must be 0 or positive"); } | RETRANS TIMER expr { RADV_IFACE->retrans_timer = $3; }
| CURRENT HOP LIMIT expr { RADV_IFACE->current_hop_limit = $4; if (($4 < 0) || ($4 > 255)) cf_error("Current hop limit must be in range 0-255"); } | CURRENT HOP LIMIT expr { RADV_IFACE->current_hop_limit = $4; if ($4 > 255) cf_error("Current hop limit must be in range 0-255"); }
| DEFAULT LIFETIME expr radv_sensitive { | DEFAULT LIFETIME expr radv_sensitive {
RADV_IFACE->default_lifetime = $3; RADV_IFACE->default_lifetime = $3;
if (($3 < 0) || ($3 > 9000)) cf_error("Default lifetime must be in range 0-9000"); if ($3 > 9000) cf_error("Default lifetime must be in range 0-9000");
if ($4 != -1) RADV_IFACE->default_lifetime_sensitive = $4; if ($4 != (uint) -1) RADV_IFACE->default_lifetime_sensitive = $4;
} }
| DEFAULT PREFERENCE radv_preference { RADV_IFACE->default_preference = $3; } | DEFAULT PREFERENCE radv_preference { RADV_IFACE->default_preference = $3; }
| PREFIX radv_prefix { add_tail(&RADV_IFACE->pref_list, NODE this_radv_prefix); } | PREFIX radv_prefix { add_tail(&RADV_IFACE->pref_list, NODE this_radv_prefix); }
@ -125,7 +125,7 @@ radv_iface_finish:
if ((ic->min_ra_int > 3) && if ((ic->min_ra_int > 3) &&
(ic->min_ra_int > (ic->max_ra_int * 3 / 4))) (ic->min_ra_int > (ic->max_ra_int * 3 / 4)))
cf_error("Min RA interval must be at most 3/4 * Max RA interval %d %d", ic->min_ra_int, ic->max_ra_int); cf_error("Min RA interval must be at most 3/4 * Max RA interval");
if ((ic->default_lifetime > 0) && (ic->default_lifetime < ic->max_ra_int)) if ((ic->default_lifetime > 0) && (ic->default_lifetime < ic->max_ra_int))
cf_error("Default lifetime must be either 0 or at least Max RA interval"); cf_error("Default lifetime must be either 0 or at least Max RA interval");
@ -163,13 +163,11 @@ radv_prefix_item:
| AUTONOMOUS bool { RADV_PREFIX->autonomous = $2; } | AUTONOMOUS bool { RADV_PREFIX->autonomous = $2; }
| VALID LIFETIME expr radv_sensitive { | VALID LIFETIME expr radv_sensitive {
RADV_PREFIX->valid_lifetime = $3; RADV_PREFIX->valid_lifetime = $3;
if ($3 < 0) cf_error("Valid lifetime must be 0 or positive"); if ($4 != (uint) -1) RADV_PREFIX->valid_lifetime_sensitive = $4;
if ($4 != -1) RADV_PREFIX->valid_lifetime_sensitive = $4;
} }
| PREFERRED LIFETIME expr radv_sensitive { | PREFERRED LIFETIME expr radv_sensitive {
RADV_PREFIX->preferred_lifetime = $3; RADV_PREFIX->preferred_lifetime = $3;
if ($3 < 0) cf_error("Preferred lifetime must be 0 or positive"); if ($4 != (uint) -1) RADV_PREFIX->preferred_lifetime_sensitive = $4;
if ($4 != -1) RADV_PREFIX->preferred_lifetime_sensitive = $4;
} }
; ;

View File

@ -65,7 +65,7 @@ rip_proto_item:
proto_item proto_item
| proto_channel | proto_channel
| ECMP bool { RIP_CFG->ecmp = $2 ? RIP_DEFAULT_ECMP_LIMIT : 0; } | ECMP bool { RIP_CFG->ecmp = $2 ? RIP_DEFAULT_ECMP_LIMIT : 0; }
| ECMP bool LIMIT expr { RIP_CFG->ecmp = $2 ? $4 : 0; if ($4 < 0) cf_error("ECMP limit cannot be negative"); } | ECMP bool LIMIT expr { RIP_CFG->ecmp = $2 ? $4 : 0; }
| INFINITY expr { RIP_CFG->infinity = $2; } | INFINITY expr { RIP_CFG->infinity = $2; }
| INTERFACE rip_iface | INTERFACE rip_iface
; ;

View File

@ -450,7 +450,7 @@ rip_send_response(struct rip_proto *p, struct rip_iface *ifa)
/* Stale entries that should be removed */ /* Stale entries that should be removed */
if ((en->valid == RIP_ENTRY_STALE) && if ((en->valid == RIP_ENTRY_STALE) &&
((en->changed + ifa->cf->garbage_time) <= now)) ((en->changed + (bird_clock_t) ifa->cf->garbage_time) <= now))
goto next_entry; goto next_entry;
/* Triggered updates */ /* Triggered updates */

View File

@ -684,7 +684,7 @@ rip_reconfigure_iface(struct rip_proto *p, struct rip_iface *ifa, struct rip_ifa
rip_iface_update_buffers(ifa); rip_iface_update_buffers(ifa);
if (ifa->next_regular > (now + new->update_time)) if (ifa->next_regular > (now + (bird_clock_t) new->update_time))
ifa->next_regular = now + (random() % new->update_time) + 1; ifa->next_regular = now + (random() % new->update_time) + 1;
if (new->check_link != old->check_link) if (new->check_link != old->check_link)

View File

@ -62,8 +62,8 @@
#ifndef HAVE_STRUCT_RTVIA #ifndef HAVE_STRUCT_RTVIA
struct rtvia { struct rtvia {
__kernel_sa_family_t rtvia_family; unsigned short rtvia_family;
__u8 rtvia_addr[0]; u8 rtvia_addr[0];
}; };
#endif #endif

View File

@ -1344,6 +1344,7 @@ sk_tcp_connected(sock *s)
s->tx_hook(s); s->tx_hook(s);
} }
#ifdef HAVE_LIBSSH
static void static void
sk_ssh_connected(sock *s) sk_ssh_connected(sock *s)
{ {
@ -1351,6 +1352,7 @@ sk_ssh_connected(sock *s)
s->type = SK_SSH; s->type = SK_SSH;
s->tx_hook(s); s->tx_hook(s);
} }
#endif
static int static int
sk_passive_connected(sock *s, int type) sk_passive_connected(sock *s, int type)

View File

@ -19,14 +19,14 @@ typedef struct timer {
resource r; resource r;
void (*hook)(struct timer *); void (*hook)(struct timer *);
void *data; void *data;
unsigned randomize; /* Amount of randomization */ uint randomize; /* Amount of randomization */
unsigned recurrent; /* Timer recurrence */ uint recurrent; /* Timer recurrence */
node n; /* Internal link */ node n; /* Internal link */
bird_clock_t expires; /* 0=inactive */ bird_clock_t expires; /* 0=inactive */
} timer; } timer;
timer *tm_new(pool *); timer *tm_new(pool *);
void tm_start(timer *, unsigned after); void tm_start(timer *, uint after);
void tm_stop(timer *); void tm_stop(timer *);
void tm_dump_all(void); void tm_dump_all(void);
@ -47,14 +47,14 @@ tm_remains(timer *t)
} }
static inline void static inline void
tm_start_max(timer *t, unsigned after) tm_start_max(timer *t, bird_clock_t after)
{ {
bird_clock_t rem = tm_remains(t); bird_clock_t rem = tm_remains(t);
tm_start(t, (rem > after) ? rem : after); tm_start(t, (rem > after) ? rem : after);
} }
static inline timer * static inline timer *
tm_new_set(pool *p, void (*hook)(struct timer *), void *data, unsigned rand, unsigned rec) tm_new_set(pool *p, void (*hook)(struct timer *), void *data, uint rand, uint rec)
{ {
timer *t = tm_new(p); timer *t = tm_new(p);
t->hook = hook; t->hook = hook;