mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Conf: Symbol implementation converted from void pointers to union
... and consted some declarations.
This commit is contained in:
parent
132529ce89
commit
0b39b1cbb7
@ -539,11 +539,8 @@ cf_new_symbol(byte *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_allocz(sizeof(struct symbol) + l + 1);
|
||||||
s->scope = conf_this_scope;
|
*s = (struct symbol) { .scope = conf_this_scope, .class = SYM_VOID, };
|
||||||
s->class = SYM_VOID;
|
|
||||||
s->def = NULL;
|
|
||||||
s->aux = 0;
|
|
||||||
strcpy(s->name, c);
|
strcpy(s->name, c);
|
||||||
|
|
||||||
if (!new_config->sym_hash.data)
|
if (!new_config->sym_hash.data)
|
||||||
@ -574,6 +571,7 @@ cf_find_symbol(struct config *cfg, byte *c)
|
|||||||
(s = HASH_FIND(cfg->sym_hash, SYM, c, 1)))
|
(s = HASH_FIND(cfg->sym_hash, SYM, c, 1)))
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
|
/* In CLI command parsing, fallback points to the current config, otherwise it is NULL. */
|
||||||
if (cfg->fallback &&
|
if (cfg->fallback &&
|
||||||
cfg->fallback->sym_hash.data &&
|
cfg->fallback->sym_hash.data &&
|
||||||
(s = HASH_FIND(cfg->fallback->sym_hash, SYM, c, 1)))
|
(s = HASH_FIND(cfg->fallback->sym_hash, SYM, c, 1)))
|
||||||
@ -597,6 +595,28 @@ cf_get_symbol(byte *c)
|
|||||||
return cf_find_symbol(new_config, c) ?: cf_new_symbol(c);
|
return cf_find_symbol(new_config, c) ?: cf_new_symbol(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cf_localize_symbol - get the local instance of given symbol
|
||||||
|
* @sym: the symbol to localize
|
||||||
|
*
|
||||||
|
* This functions finds the symbol that is local to current scope
|
||||||
|
* for purposes of cf_define_symbol().
|
||||||
|
*/
|
||||||
|
struct symbol *
|
||||||
|
cf_localize_symbol(struct symbol *sym)
|
||||||
|
{
|
||||||
|
/* If the symbol type is void, it has been recently allocated just in this scope. */
|
||||||
|
if (!sym->class)
|
||||||
|
return sym;
|
||||||
|
|
||||||
|
/* If the scope is the current, it is already defined in this scope. */
|
||||||
|
if (sym->scope == conf_this_scope)
|
||||||
|
cf_error("Symbol already defined");
|
||||||
|
|
||||||
|
/* Not allocated here yet, doing it now. */
|
||||||
|
return cf_new_symbol(sym->name);
|
||||||
|
}
|
||||||
|
|
||||||
struct symbol *
|
struct symbol *
|
||||||
cf_default_name(char *template, int *counter)
|
cf_default_name(char *template, int *counter)
|
||||||
{
|
{
|
||||||
@ -616,35 +636,6 @@ cf_default_name(char *template, int *counter)
|
|||||||
cf_error("Unable to generate default name");
|
cf_error("Unable to generate default name");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* cf_define_symbol - define meaning of a symbol
|
|
||||||
* @sym: symbol to be defined
|
|
||||||
* @type: symbol class to assign
|
|
||||||
* @def: class dependent data
|
|
||||||
*
|
|
||||||
* Defines new meaning of a symbol. If the symbol is an undefined
|
|
||||||
* one (%SYM_VOID), it's just re-defined to the new type. If it's defined
|
|
||||||
* in different scope, a new symbol in current scope is created and the
|
|
||||||
* meaning is assigned to it. If it's already defined in the current scope,
|
|
||||||
* an error is reported via cf_error().
|
|
||||||
*
|
|
||||||
* Result: Pointer to the newly defined symbol. If we are in the top-level
|
|
||||||
* scope, it's the same @sym as passed to the function.
|
|
||||||
*/
|
|
||||||
struct symbol *
|
|
||||||
cf_define_symbol(struct symbol *sym, int type, void *def)
|
|
||||||
{
|
|
||||||
if (sym->class)
|
|
||||||
{
|
|
||||||
if (sym->scope == conf_this_scope)
|
|
||||||
cf_error("Symbol already defined");
|
|
||||||
sym = cf_new_symbol(sym->name);
|
|
||||||
}
|
|
||||||
sym->class = type;
|
|
||||||
sym->def = def;
|
|
||||||
return sym;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cf_lex_init_kh(void)
|
cf_lex_init_kh(void)
|
||||||
{
|
{
|
||||||
|
49
conf/conf.h
49
conf/conf.h
@ -105,11 +105,19 @@ extern int (*cf_read_hook)(byte *buf, uint max, int fd);
|
|||||||
struct symbol {
|
struct symbol {
|
||||||
struct symbol *next;
|
struct symbol *next;
|
||||||
struct sym_scope *scope;
|
struct sym_scope *scope;
|
||||||
int class;
|
int class; /* SYM_* */
|
||||||
int aux;
|
uint flags; /* SYM_FLAG_* */
|
||||||
uint aux2;
|
|
||||||
void *def;
|
union {
|
||||||
char name[1];
|
struct proto_config *proto; /* For SYM_PROTO and SYM_TEMPLATE */
|
||||||
|
const struct f_line *function; /* For SYM_FUNCTION */
|
||||||
|
const struct filter *filter; /* For SYM_FILTER */
|
||||||
|
struct rtable_config *table; /* For SYM_TABLE */
|
||||||
|
struct f_dynamic_attr *attribute; /* For SYM_ATTRIBUTE */
|
||||||
|
struct f_val *val; /* For SYM_CONSTANT or SYM_VARIABLE */
|
||||||
|
};
|
||||||
|
|
||||||
|
char name[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sym_scope {
|
struct sym_scope {
|
||||||
@ -134,8 +142,11 @@ struct sym_scope {
|
|||||||
#define SYM_CONSTANT 0x200 /* 0x200-0x2ff are variable types */
|
#define SYM_CONSTANT 0x200 /* 0x200-0x2ff are variable types */
|
||||||
#define SYM_CONSTANT_RANGE SYM_CONSTANT ... (SYM_CONSTANT | 0xff)
|
#define SYM_CONSTANT_RANGE SYM_CONSTANT ... (SYM_CONSTANT | 0xff)
|
||||||
|
|
||||||
#define SYM_TYPE(s) (((struct f_val *) (s)->def)->type)
|
#define SYM_TYPE(s) ((s)->val->type)
|
||||||
#define SYM_VAL(s) (((struct f_val *) (s)->def)->val)
|
#define SYM_VAL(s) ((s)->val->val)
|
||||||
|
|
||||||
|
/* Symbol flags */
|
||||||
|
#define SYM_FLAG_SAME 0x1 /* For SYM_FUNCTION and SYM_FILTER */
|
||||||
|
|
||||||
struct include_file_stack {
|
struct include_file_stack {
|
||||||
void *buffer; /* Internal lexer state */
|
void *buffer; /* Internal lexer state */
|
||||||
@ -160,7 +171,29 @@ struct symbol *cf_find_symbol(struct config *cfg, byte *c);
|
|||||||
|
|
||||||
struct symbol *cf_get_symbol(byte *c);
|
struct symbol *cf_get_symbol(byte *c);
|
||||||
struct symbol *cf_default_name(char *template, int *counter);
|
struct symbol *cf_default_name(char *template, int *counter);
|
||||||
struct symbol *cf_define_symbol(struct symbol *symbol, int type, void *def);
|
struct symbol *cf_localize_symbol(struct symbol *sym);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cf_define_symbol - define meaning of a symbol
|
||||||
|
* @sym: symbol to be defined
|
||||||
|
* @type: symbol class to assign
|
||||||
|
* @def: class dependent data
|
||||||
|
*
|
||||||
|
* Defines new meaning of a symbol. If the symbol is an undefined
|
||||||
|
* one (%SYM_VOID), it's just re-defined to the new type. If it's defined
|
||||||
|
* in different scope, a new symbol in current scope is created and the
|
||||||
|
* meaning is assigned to it. If it's already defined in the current scope,
|
||||||
|
* an error is reported via cf_error().
|
||||||
|
*
|
||||||
|
* Result: Pointer to the newly defined symbol. If we are in the top-level
|
||||||
|
* scope, it's the same @sym as passed to the function.
|
||||||
|
*/
|
||||||
|
#define cf_define_symbol(sym_, type_, var_, def_) ({ \
|
||||||
|
struct symbol *sym = cf_localize_symbol(sym_); \
|
||||||
|
sym->class = type_; \
|
||||||
|
sym->var_ = def_; \
|
||||||
|
sym; })
|
||||||
|
|
||||||
void cf_push_scope(struct symbol *);
|
void cf_push_scope(struct symbol *);
|
||||||
void cf_pop_scope(void);
|
void cf_pop_scope(void);
|
||||||
char *cf_symbol_class_name(struct symbol *sym);
|
char *cf_symbol_class_name(struct symbol *sym);
|
||||||
|
@ -56,7 +56,8 @@ CF_DECLS
|
|||||||
struct f_dynamic_attr fda;
|
struct f_dynamic_attr fda;
|
||||||
struct f_static_attr fsa;
|
struct f_static_attr fsa;
|
||||||
struct f_lval flv;
|
struct f_lval flv;
|
||||||
struct filter *f;
|
const struct f_line *fl;
|
||||||
|
const struct filter *f;
|
||||||
struct f_tree *e;
|
struct f_tree *e;
|
||||||
struct f_trie *trie;
|
struct f_trie *trie;
|
||||||
struct f_val v;
|
struct f_val v;
|
||||||
@ -130,7 +131,7 @@ definition:
|
|||||||
DEFINE CF_SYM_VOID '=' term ';' {
|
DEFINE CF_SYM_VOID '=' term ';' {
|
||||||
struct f_val *val = cfg_alloc(sizeof(struct f_val));
|
struct f_val *val = cfg_alloc(sizeof(struct f_val));
|
||||||
if (f_eval(f_postfixify($4), cfg_mem, val) > F_RETURN) cf_error("Runtime error");
|
if (f_eval(f_postfixify($4), cfg_mem, val) > F_RETURN) cf_error("Runtime error");
|
||||||
cf_define_symbol($2, SYM_CONSTANT | val->type, val);
|
cf_define_symbol($2, SYM_CONSTANT | val->type, val, val);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -451,7 +451,8 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
|
|||||||
%type <x> term block cmd cmds constant constructor print_one print_list var_list var_listn function_call symbol_value bgp_path_expr bgp_path bgp_path_tail one_decl decls
|
%type <x> term block cmd cmds constant constructor print_one print_list var_list var_listn function_call symbol_value bgp_path_expr bgp_path bgp_path_tail one_decl decls
|
||||||
%type <fda> dynamic_attr
|
%type <fda> dynamic_attr
|
||||||
%type <fsa> static_attr
|
%type <fsa> static_attr
|
||||||
%type <f> filter filter_body where_filter
|
%type <f> filter where_filter
|
||||||
|
%type <fl> filter_body
|
||||||
%type <flv> lvalue
|
%type <flv> lvalue
|
||||||
%type <i> type
|
%type <i> type
|
||||||
%type <ecs> ec_kind
|
%type <ecs> ec_kind
|
||||||
@ -467,11 +468,12 @@ CF_GRAMMAR
|
|||||||
|
|
||||||
conf: filter_def ;
|
conf: filter_def ;
|
||||||
filter_def:
|
filter_def:
|
||||||
FILTER CF_SYM_VOID { $2 = cf_define_symbol($2, SYM_FILTER, NULL); cf_push_scope( $2 ); }
|
FILTER CF_SYM_VOID { $2 = cf_define_symbol($2, SYM_FILTER, filter, NULL); cf_push_scope( $2 ); }
|
||||||
filter_body {
|
filter_body {
|
||||||
$2->def = $4;
|
struct filter *f = cfg_alloc(sizeof(struct filter));
|
||||||
$4->name = $2->name;
|
*f = (struct filter) { .name = $2->name, .root = $4 };
|
||||||
DBG( "We have new filter defined (%s)\n", $2->name );
|
$2->filter = f;
|
||||||
|
|
||||||
cf_pop_scope();
|
cf_pop_scope();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -483,14 +485,14 @@ filter_eval:
|
|||||||
|
|
||||||
conf: custom_attr ;
|
conf: custom_attr ;
|
||||||
custom_attr: ATTRIBUTE type CF_SYM_VOID ';' {
|
custom_attr: ATTRIBUTE type CF_SYM_VOID ';' {
|
||||||
cf_define_symbol($3, SYM_ATTRIBUTE, ca_lookup(new_config->pool, $3->name, $2)->fda);
|
cf_define_symbol($3, SYM_ATTRIBUTE, attribute, ca_lookup(new_config->pool, $3->name, $2)->fda);
|
||||||
};
|
};
|
||||||
|
|
||||||
conf: bt_test_suite ;
|
conf: bt_test_suite ;
|
||||||
bt_test_suite:
|
bt_test_suite:
|
||||||
BT_TEST_SUITE '(' CF_SYM_FUNCTION ',' text ')' {
|
BT_TEST_SUITE '(' CF_SYM_FUNCTION ',' text ')' {
|
||||||
struct f_bt_test_suite *t = cfg_allocz(sizeof(struct f_bt_test_suite));
|
struct f_bt_test_suite *t = cfg_allocz(sizeof(struct f_bt_test_suite));
|
||||||
t->fn = $3->def;
|
t->fn = $3->function;
|
||||||
t->fn_name = $3->name;
|
t->fn_name = $3->name;
|
||||||
t->dsc = $5;
|
t->dsc = $5;
|
||||||
|
|
||||||
@ -502,8 +504,8 @@ conf: bt_test_same ;
|
|||||||
bt_test_same:
|
bt_test_same:
|
||||||
BT_TEST_SAME '(' CF_SYM_FUNCTION ',' CF_SYM_FUNCTION ',' NUM ')' {
|
BT_TEST_SAME '(' CF_SYM_FUNCTION ',' CF_SYM_FUNCTION ',' NUM ')' {
|
||||||
struct f_bt_test_suite *t = cfg_allocz(sizeof(struct f_bt_test_suite));
|
struct f_bt_test_suite *t = cfg_allocz(sizeof(struct f_bt_test_suite));
|
||||||
t->fn = $3->def;
|
t->fn = $3->function;
|
||||||
t->cmp = $5->def;
|
t->cmp = $5->function;
|
||||||
t->result = $7;
|
t->result = $7;
|
||||||
t->fn_name = $3->name;
|
t->fn_name = $3->name;
|
||||||
t->dsc = $5->name;
|
t->dsc = $5->name;
|
||||||
@ -553,7 +555,7 @@ one_decl:
|
|||||||
type CF_SYM_VOID {
|
type CF_SYM_VOID {
|
||||||
struct f_val * val = cfg_alloc(sizeof(struct f_val));
|
struct f_val * val = cfg_alloc(sizeof(struct f_val));
|
||||||
val->type = T_VOID;
|
val->type = T_VOID;
|
||||||
$2 = cf_define_symbol($2, SYM_VARIABLE | $1, val);
|
$2 = cf_define_symbol($2, SYM_VARIABLE | $1, val, val);
|
||||||
DBG( "New variable %s type %x\n", $2->name, $1 );
|
DBG( "New variable %s type %x\n", $2->name, $1 );
|
||||||
$$ = f_new_inst(FI_SET, NULL, $2);
|
$$ = f_new_inst(FI_SET, NULL, $2);
|
||||||
}
|
}
|
||||||
@ -578,22 +580,24 @@ declsn: one_decl { $$.inst = $1; $$.count = 1; }
|
|||||||
|
|
||||||
filter_body:
|
filter_body:
|
||||||
function_body {
|
function_body {
|
||||||
$$ = cfg_alloc(sizeof(struct filter));
|
|
||||||
$$->name = NULL;
|
|
||||||
if ($1[0]) {
|
if ($1[0]) {
|
||||||
const struct f_inst *inst[2] = { $1[0], $1[1] };
|
const struct f_inst *inst[2] = { $1[0], $1[1] };
|
||||||
$$->root = f_postfixify_concat(inst, 2);
|
$$ = f_postfixify_concat(inst, 2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
$$->root = f_postfixify($1[1]);
|
$$ = f_postfixify($1[1]);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
filter:
|
filter:
|
||||||
CF_SYM_FILTER {
|
CF_SYM_FILTER {
|
||||||
$$ = $1->def;
|
$$ = $1->filter;
|
||||||
|
}
|
||||||
|
| filter_body {
|
||||||
|
struct filter *f = cfg_alloc(sizeof(struct filter));
|
||||||
|
*f = (struct filter) { .root = $1 };
|
||||||
|
$$ = f;
|
||||||
}
|
}
|
||||||
| filter_body
|
|
||||||
;
|
;
|
||||||
|
|
||||||
where_filter:
|
where_filter:
|
||||||
@ -618,7 +622,7 @@ function_body:
|
|||||||
conf: function_def ;
|
conf: function_def ;
|
||||||
function_def:
|
function_def:
|
||||||
FUNCTION CF_SYM_VOID { DBG( "Beginning of function %s\n", $2->name );
|
FUNCTION CF_SYM_VOID { DBG( "Beginning of function %s\n", $2->name );
|
||||||
$2 = cf_define_symbol($2, SYM_FUNCTION, NULL);
|
$2 = cf_define_symbol($2, SYM_FUNCTION, function, NULL);
|
||||||
cf_push_scope($2);
|
cf_push_scope($2);
|
||||||
} function_params function_body {
|
} function_params function_body {
|
||||||
const struct f_inst *catlist[4];
|
const struct f_inst *catlist[4];
|
||||||
@ -639,9 +643,10 @@ function_def:
|
|||||||
if ($5[1])
|
if ($5[1])
|
||||||
catlist[count++] = $5[1];
|
catlist[count++] = $5[1];
|
||||||
|
|
||||||
$2->def = f_postfixify_concat(catlist, count);
|
struct f_line *fl = f_postfixify_concat(catlist, count);
|
||||||
$2->aux2 = $4.count;
|
fl->args = $4.count;
|
||||||
DBG("Hmm, we've got one function here - %s\n", $2->name);
|
$2->function = fl;
|
||||||
|
|
||||||
cf_pop_scope();
|
cf_pop_scope();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -693,7 +698,7 @@ set_atom:
|
|||||||
}
|
}
|
||||||
| CF_SYM_CONSTANT {
|
| CF_SYM_CONSTANT {
|
||||||
if (!f_valid_set_type(SYM_TYPE($1))) cf_error("%s: set-incompatible type", $1->name);
|
if (!f_valid_set_type(SYM_TYPE($1))) cf_error("%s: set-incompatible type", $1->name);
|
||||||
$$ = *(struct f_val *)($1->def);
|
$$ = *$1->val;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -856,9 +861,9 @@ function_call:
|
|||||||
;
|
;
|
||||||
|
|
||||||
symbol_value:
|
symbol_value:
|
||||||
CF_SYM_CONSTANT { $$ = f_new_inst(FI_CONSTANT_INDIRECT, $1->def); }
|
CF_SYM_CONSTANT { $$ = f_new_inst(FI_CONSTANT_INDIRECT, $1->val); }
|
||||||
| CF_SYM_VARIABLE { $$ = f_new_inst(FI_VARIABLE, $1); }
|
| CF_SYM_VARIABLE { $$ = f_new_inst(FI_VARIABLE, $1); }
|
||||||
| CF_SYM_ATTRIBUTE { $$ = f_new_inst(FI_EA_GET, *((struct f_dynamic_attr *) $1->def)); }
|
| CF_SYM_ATTRIBUTE { $$ = f_new_inst(FI_EA_GET, *$1->attribute); }
|
||||||
;
|
;
|
||||||
|
|
||||||
static_attr:
|
static_attr:
|
||||||
@ -986,7 +991,7 @@ cmd:
|
|||||||
$$ = f_new_inst(FI_CONDITION, $2, $4, $6);
|
$$ = f_new_inst(FI_CONDITION, $2, $4, $6);
|
||||||
}
|
}
|
||||||
| CF_SYM_ATTRIBUTE '=' term ';' {
|
| CF_SYM_ATTRIBUTE '=' term ';' {
|
||||||
$$ = f_new_inst(FI_EA_SET, $3, *((struct f_dynamic_attr *) $1->def));
|
$$ = f_new_inst(FI_EA_SET, $3, *$1->attribute);
|
||||||
}
|
}
|
||||||
| CF_SYM_VARIABLE '=' term ';' {
|
| CF_SYM_VARIABLE '=' term ';' {
|
||||||
$$ = f_new_inst(FI_SET, $3, $1);
|
$$ = f_new_inst(FI_SET, $3, $1);
|
||||||
|
@ -188,9 +188,9 @@ const struct symbol *sym;
|
|||||||
FID_NEW_ARGS
|
FID_NEW_ARGS
|
||||||
, const struct symbol *sym
|
, const struct symbol *sym
|
||||||
FID_NEW_BODY
|
FID_NEW_BODY
|
||||||
what->valp = (what->sym = sym)->def;
|
what->valp = (what->sym = sym)->val;
|
||||||
FID_POSTFIXIFY_BODY
|
FID_POSTFIXIFY_BODY
|
||||||
dest->items[pos].vp = (dest->items[pos].sym = what->sym)->def;
|
dest->items[pos].vp = (dest->items[pos].sym = what->sym)->val;
|
||||||
FID_SAME_BODY
|
FID_SAME_BODY
|
||||||
if (strcmp(f1->sym->name, f2->sym->name) || (f1->sym->class != f2->sym->class)) return 0;
|
if (strcmp(f1->sym->name, f2->sym->name) || (f1->sym->class != f2->sym->class)) return 0;
|
||||||
FID_DUMP_BODY
|
FID_DUMP_BODY
|
||||||
|
@ -233,7 +233,7 @@
|
|||||||
/* IP->Quad implicit conversion */
|
/* IP->Quad implicit conversion */
|
||||||
if ((sym->class == (SYM_VARIABLE | T_QUAD)) && val_is_ip4(&v1))
|
if ((sym->class == (SYM_VARIABLE | T_QUAD)) && val_is_ip4(&v1))
|
||||||
{
|
{
|
||||||
*((struct f_val *) sym->def) = (struct f_val) {
|
*(sym->val) = (struct f_val) {
|
||||||
.type = T_QUAD,
|
.type = T_QUAD,
|
||||||
.val.i = ipa_to_u32(v1.val.ip),
|
.val.i = ipa_to_u32(v1.val.ip),
|
||||||
};
|
};
|
||||||
@ -241,7 +241,7 @@
|
|||||||
}
|
}
|
||||||
runtime( "Assigning to variable of incompatible type" );
|
runtime( "Assigning to variable of incompatible type" );
|
||||||
}
|
}
|
||||||
*((struct f_val *) sym->def) = v1;
|
*(sym->val) = v1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* some constants have value in a[1], some in *a[0].p, strange. */
|
/* some constants have value in a[1], some in *a[0].p, strange. */
|
||||||
@ -709,7 +709,7 @@
|
|||||||
|
|
||||||
/* Postfixify extracts the function body from the symbol */
|
/* Postfixify extracts the function body from the symbol */
|
||||||
FID_POSTFIXIFY_BODY
|
FID_POSTFIXIFY_BODY
|
||||||
dest->items[pos].lines[0] = what->sym->def;
|
dest->items[pos].lines[0] = what->sym->function;
|
||||||
FID_END
|
FID_END
|
||||||
|
|
||||||
/* First push the body on stack */
|
/* First push the body on stack */
|
||||||
@ -727,8 +727,8 @@
|
|||||||
for (const struct f_inst *inst = f1; inst; inst = inst->next)
|
for (const struct f_inst *inst = f1; inst; inst = inst->next)
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
if (count != sym->aux2)
|
if (count != sym->function->args)
|
||||||
cf_error("Function %s takes %u arguments, got %u.", sym->name, sym->aux2, count);
|
cf_error("Function %s takes %u arguments, got %u.", sym->name, sym->function->args, count);
|
||||||
FID_END
|
FID_END
|
||||||
|
|
||||||
/* FIXME: Optimization of function comparison. */
|
/* FIXME: Optimization of function comparison. */
|
||||||
|
@ -59,6 +59,7 @@ struct f_line_item {
|
|||||||
/* Line of instructions to be unconditionally executed one after another */
|
/* Line of instructions to be unconditionally executed one after another */
|
||||||
struct f_line {
|
struct f_line {
|
||||||
uint len; /* Line length */
|
uint len; /* Line length */
|
||||||
|
u16 args; /* Function: Args required */
|
||||||
struct f_line_item items[0]; /* The items themselves */
|
struct f_line_item items[0]; /* The items themselves */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,8 +82,8 @@ extern void (*bt_assert_hook)(int result, const struct f_line_item *assert);
|
|||||||
/* Bird Tests */
|
/* Bird Tests */
|
||||||
struct f_bt_test_suite {
|
struct f_bt_test_suite {
|
||||||
node n; /* Node in config->tests */
|
node n; /* Node in config->tests */
|
||||||
struct f_line *fn; /* Root of function */
|
const struct f_line *fn; /* Root of function */
|
||||||
struct f_line *cmp; /* Compare to this function */
|
const struct f_line *cmp; /* Compare to this function */
|
||||||
const char *fn_name; /* Name of test */
|
const char *fn_name; /* Name of test */
|
||||||
const char *dsc; /* Description */
|
const char *dsc; /* Description */
|
||||||
int result; /* Desired result */
|
int result; /* Desired result */
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
|
|
||||||
#define P(a,b) ((a<<8) | b)
|
#define P(a,b) ((a<<8) | b)
|
||||||
|
|
||||||
char *
|
const char *
|
||||||
filter_name(struct filter *filter)
|
filter_name(const struct filter *filter)
|
||||||
{
|
{
|
||||||
if (!filter)
|
if (!filter)
|
||||||
return "ACCEPT";
|
return "ACCEPT";
|
||||||
|
@ -359,15 +359,14 @@ f_eval_buf(const struct f_line *expr, struct linpool *tmp_pool, buffer *buf)
|
|||||||
/**
|
/**
|
||||||
* filter_same - compare two filters
|
* filter_same - compare two filters
|
||||||
* @new: first filter to be compared
|
* @new: first filter to be compared
|
||||||
* @old: second filter to be compared, notice that this filter is
|
* @old: second filter to be compared
|
||||||
* damaged while comparing.
|
|
||||||
*
|
*
|
||||||
* Returns 1 in case filters are same, otherwise 0. If there are
|
* Returns 1 in case filters are same, otherwise 0. If there are
|
||||||
* underlying bugs, it will rather say 0 on same filters than say
|
* underlying bugs, it will rather say 0 on same filters than say
|
||||||
* 1 on different.
|
* 1 on different.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
filter_same(struct filter *new, struct filter *old)
|
filter_same(const struct filter *new, const struct filter *old)
|
||||||
{
|
{
|
||||||
if (old == new) /* Handle FILTER_ACCEPT and FILTER_REJECT */
|
if (old == new) /* Handle FILTER_ACCEPT and FILTER_REJECT */
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -48,7 +48,7 @@ struct f_val;
|
|||||||
struct f_line;
|
struct f_line;
|
||||||
struct filter {
|
struct filter {
|
||||||
char *name;
|
char *name;
|
||||||
struct f_line *root;
|
const struct f_line *root;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rte;
|
struct rte;
|
||||||
@ -58,8 +58,8 @@ enum filter_return f_eval_rte(const struct f_line *expr, struct rte **rte, struc
|
|||||||
uint f_eval_int(const struct f_line *expr);
|
uint f_eval_int(const struct f_line *expr);
|
||||||
enum filter_return f_eval_buf(const struct f_line *expr, struct linpool *tmp_pool, buffer *buf);
|
enum filter_return f_eval_buf(const struct f_line *expr, struct linpool *tmp_pool, buffer *buf);
|
||||||
|
|
||||||
char *filter_name(struct filter *filter);
|
const char *filter_name(const struct filter *filter);
|
||||||
int filter_same(struct filter *new, struct filter *old);
|
int filter_same(const struct filter *new, const struct filter *old);
|
||||||
int f_same(const struct f_line *f1, const struct f_line *f2);
|
int f_same(const struct f_line *f1, const struct f_line *f2);
|
||||||
|
|
||||||
#define FILTER_ACCEPT NULL
|
#define FILTER_ACCEPT NULL
|
||||||
|
@ -179,28 +179,28 @@ proto_name:
|
|||||||
/* EMPTY */ {
|
/* EMPTY */ {
|
||||||
struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
|
struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
|
||||||
s->class = this_proto->class;
|
s->class = this_proto->class;
|
||||||
s->def = this_proto;
|
s->proto = this_proto;
|
||||||
this_proto->name = s->name;
|
this_proto->name = s->name;
|
||||||
}
|
}
|
||||||
| CF_SYM_VOID {
|
| CF_SYM_VOID {
|
||||||
cf_define_symbol($1, this_proto->class, this_proto);
|
cf_define_symbol($1, this_proto->class, proto, this_proto);
|
||||||
this_proto->name = $1->name;
|
this_proto->name = $1->name;
|
||||||
}
|
}
|
||||||
| FROM sym_proto_or_template {
|
| FROM sym_proto_or_template {
|
||||||
struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
|
struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
|
||||||
s->class = this_proto->class;
|
s->class = this_proto->class;
|
||||||
s->def = this_proto;
|
s->proto = this_proto;
|
||||||
this_proto->name = s->name;
|
this_proto->name = s->name;
|
||||||
|
|
||||||
if (($2->class != SYM_TEMPLATE) && ($2->class != SYM_PROTO)) cf_error("Template or protocol name expected");
|
if (($2->class != SYM_TEMPLATE) && ($2->class != SYM_PROTO)) cf_error("Template or protocol name expected");
|
||||||
proto_copy_config(this_proto, $2->def);
|
proto_copy_config(this_proto, $2->proto);
|
||||||
}
|
}
|
||||||
| CF_SYM_VOID FROM sym_proto_or_template {
|
| CF_SYM_VOID FROM sym_proto_or_template {
|
||||||
cf_define_symbol($1, this_proto->class, this_proto);
|
cf_define_symbol($1, this_proto->class, proto, this_proto);
|
||||||
this_proto->name = $1->name;
|
this_proto->name = $1->name;
|
||||||
|
|
||||||
if (($3->class != SYM_TEMPLATE) && ($3->class != SYM_PROTO)) cf_error("Template or protocol name expected");
|
if (($3->class != SYM_TEMPLATE) && ($3->class != SYM_PROTO)) cf_error("Template or protocol name expected");
|
||||||
proto_copy_config(this_proto, $3->def);
|
proto_copy_config(this_proto, $3->proto);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ channel_end:
|
|||||||
proto_channel: channel_start channel_opt_list channel_end;
|
proto_channel: channel_start channel_opt_list channel_end;
|
||||||
|
|
||||||
|
|
||||||
rtable: CF_SYM_TABLE { $$ = $1->def; } ;
|
rtable: CF_SYM_TABLE { $$ = $1->table; } ;
|
||||||
|
|
||||||
imexport:
|
imexport:
|
||||||
FILTER filter { $$ = $2; }
|
FILTER filter { $$ = $2; }
|
||||||
@ -544,7 +544,7 @@ r_args:
|
|||||||
}
|
}
|
||||||
| r_args TABLE CF_SYM_TABLE {
|
| r_args TABLE CF_SYM_TABLE {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
rt_show_add_table($$, ((struct rtable_config *)$3->def)->table);
|
rt_show_add_table($$, $3->table->table);
|
||||||
$$->tables_defined_by = RSD_TDB_DIRECT;
|
$$->tables_defined_by = RSD_TDB_DIRECT;
|
||||||
}
|
}
|
||||||
| r_args TABLE ALL {
|
| r_args TABLE ALL {
|
||||||
@ -556,7 +556,7 @@ r_args:
|
|||||||
}
|
}
|
||||||
| r_args IMPORT TABLE CF_SYM_PROTO '.' r_args_channel {
|
| r_args IMPORT TABLE CF_SYM_PROTO '.' r_args_channel {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
struct proto_config *cf = (void *) $4->def;
|
struct proto_config *cf = $4->proto;
|
||||||
if (!cf->proto) cf_error("%s is not a protocol", $4->name);
|
if (!cf->proto) cf_error("%s is not a protocol", $4->name);
|
||||||
struct channel *c = proto_find_channel_by_name(cf->proto, $6);
|
struct channel *c = proto_find_channel_by_name(cf->proto, $6);
|
||||||
if (!c) cf_error("Channel %s.%s not found", $4->name, $6);
|
if (!c) cf_error("Channel %s.%s not found", $4->name, $6);
|
||||||
@ -587,7 +587,7 @@ r_args:
|
|||||||
$$->filtered = 1;
|
$$->filtered = 1;
|
||||||
}
|
}
|
||||||
| r_args export_mode CF_SYM_PROTO {
|
| r_args export_mode CF_SYM_PROTO {
|
||||||
struct proto_config *c = (struct proto_config *) $3->def;
|
struct proto_config *c = (struct proto_config *) $3->proto;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
if ($$->export_mode) cf_error("Export specified twice");
|
if ($$->export_mode) cf_error("Export specified twice");
|
||||||
if (!c->proto) cf_error("%s is not a protocol", $3->name);
|
if (!c->proto) cf_error("%s is not a protocol", $3->name);
|
||||||
@ -596,7 +596,7 @@ r_args:
|
|||||||
$$->tables_defined_by = RSD_TDB_INDIRECT;
|
$$->tables_defined_by = RSD_TDB_INDIRECT;
|
||||||
}
|
}
|
||||||
| r_args export_mode CF_SYM_PROTO '.' r_args_channel {
|
| r_args export_mode CF_SYM_PROTO '.' r_args_channel {
|
||||||
struct proto_config *c = (struct proto_config *) $3->def;
|
struct proto_config *c = (struct proto_config *) $3->proto;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
if ($$->export_mode) cf_error("Export specified twice");
|
if ($$->export_mode) cf_error("Export specified twice");
|
||||||
if (!c->proto) cf_error("%s is not a protocol", $3->name);
|
if (!c->proto) cf_error("%s is not a protocol", $3->name);
|
||||||
@ -606,7 +606,7 @@ r_args:
|
|||||||
$$->tables_defined_by = RSD_TDB_INDIRECT;
|
$$->tables_defined_by = RSD_TDB_INDIRECT;
|
||||||
}
|
}
|
||||||
| r_args PROTOCOL CF_SYM_PROTO {
|
| r_args PROTOCOL CF_SYM_PROTO {
|
||||||
struct proto_config *c = (struct proto_config *) $3->def;
|
struct proto_config *c = (struct proto_config *) $3->proto;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
if ($$->show_protocol) cf_error("Protocol specified twice");
|
if ($$->show_protocol) cf_error("Protocol specified twice");
|
||||||
if (!c->proto) cf_error("%s is not a protocol", $3->name);
|
if (!c->proto) cf_error("%s is not a protocol", $3->name);
|
||||||
|
@ -977,7 +977,7 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
|
|||||||
{
|
{
|
||||||
/* Found match, let's check if we can smoothly switch to new configuration */
|
/* Found match, let's check if we can smoothly switch to new configuration */
|
||||||
/* No need to check description */
|
/* No need to check description */
|
||||||
nc = sym->def;
|
nc = sym->proto;
|
||||||
nc->proto = p;
|
nc->proto = p;
|
||||||
|
|
||||||
/* We will try to reconfigure protocol p */
|
/* We will try to reconfigure protocol p */
|
||||||
@ -1905,7 +1905,7 @@ proto_apply_cmd_symbol(struct symbol *s, void (* cmd)(struct proto *, uintptr_t,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd(((struct proto_config *)s->def)->proto, arg, 0);
|
cmd(s->proto->proto, arg, 0);
|
||||||
cli_msg(0, "");
|
cli_msg(0, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1948,7 +1948,7 @@ proto_get_named(struct symbol *sym, struct protocol *pr)
|
|||||||
if (sym->class != SYM_PROTO)
|
if (sym->class != SYM_PROTO)
|
||||||
cf_error("%s: Not a protocol", sym->name);
|
cf_error("%s: Not a protocol", sym->name);
|
||||||
|
|
||||||
p = ((struct proto_config *) sym->def)->proto;
|
p = sym->proto->proto;
|
||||||
if (!p || p->proto != pr)
|
if (!p || p->proto != pr)
|
||||||
cf_error("%s: Not a %s protocol", sym->name, pr->name);
|
cf_error("%s: Not a %s protocol", sym->name, pr->name);
|
||||||
}
|
}
|
||||||
|
@ -489,7 +489,7 @@ struct channel_config {
|
|||||||
|
|
||||||
struct proto_config *parent; /* Where channel is defined (proto or template) */
|
struct proto_config *parent; /* Where channel is defined (proto or template) */
|
||||||
struct rtable_config *table; /* Table we're attached to */
|
struct rtable_config *table; /* Table we're attached to */
|
||||||
struct filter *in_filter, *out_filter; /* Attached filters */
|
const struct filter *in_filter, *out_filter; /* Attached filters */
|
||||||
struct channel_limit rx_limit; /* Limit for receiving routes from protocol
|
struct channel_limit rx_limit; /* Limit for receiving routes from protocol
|
||||||
(relevant when in_keep_filtered is active) */
|
(relevant when in_keep_filtered is active) */
|
||||||
struct channel_limit in_limit; /* Limit for importing routes from protocol */
|
struct channel_limit in_limit; /* Limit for importing routes from protocol */
|
||||||
@ -511,8 +511,8 @@ struct channel {
|
|||||||
struct proto *proto;
|
struct proto *proto;
|
||||||
|
|
||||||
struct rtable *table;
|
struct rtable *table;
|
||||||
struct filter *in_filter; /* Input filter */
|
const struct filter *in_filter; /* Input filter */
|
||||||
struct filter *out_filter; /* Output filter */
|
const struct filter *out_filter; /* Output filter */
|
||||||
struct channel_limit rx_limit; /* Receive limit (for in_keep_filtered) */
|
struct channel_limit rx_limit; /* Receive limit (for in_keep_filtered) */
|
||||||
struct channel_limit in_limit; /* Input limit */
|
struct channel_limit in_limit; /* Input limit */
|
||||||
struct channel_limit out_limit; /* Output limit */
|
struct channel_limit out_limit; /* Output limit */
|
||||||
|
@ -297,7 +297,7 @@ rte *rte_find(net *net, struct rte_src *src);
|
|||||||
rte *rte_get_temp(struct rta *);
|
rte *rte_get_temp(struct rta *);
|
||||||
void rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src);
|
void rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src);
|
||||||
/* rte_update() moved to protocol.h to avoid dependency conflicts */
|
/* rte_update() moved to protocol.h to avoid dependency conflicts */
|
||||||
int rt_examine(rtable *t, net_addr *a, struct proto *p, struct filter *filter);
|
int rt_examine(rtable *t, net_addr *a, struct proto *p, const struct filter *filter);
|
||||||
rte *rt_export_merged(struct channel *c, net *net, rte **rt_free, linpool *pool, int silent);
|
rte *rt_export_merged(struct channel *c, net *net, rte **rt_free, linpool *pool, int silent);
|
||||||
void rt_refresh_begin(rtable *t, struct channel *c);
|
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);
|
||||||
@ -335,7 +335,7 @@ struct rt_show_data {
|
|||||||
struct rt_show_data_rtable *last_table; /* Last table in output */
|
struct rt_show_data_rtable *last_table; /* Last table in output */
|
||||||
struct fib_iterator fit; /* Iterator over networks in table */
|
struct fib_iterator fit; /* Iterator over networks in table */
|
||||||
int verbose, tables_defined_by;
|
int verbose, tables_defined_by;
|
||||||
struct filter *filter;
|
const struct filter *filter;
|
||||||
struct proto *show_protocol;
|
struct proto *show_protocol;
|
||||||
struct proto *export_protocol;
|
struct proto *export_protocol;
|
||||||
struct channel *export_channel;
|
struct channel *export_channel;
|
||||||
|
@ -398,7 +398,7 @@ static rte *
|
|||||||
export_filter_(struct channel *c, rte *rt0, rte **rt_free, linpool *pool, int silent)
|
export_filter_(struct channel *c, rte *rt0, rte **rt_free, linpool *pool, int silent)
|
||||||
{
|
{
|
||||||
struct proto *p = c->proto;
|
struct proto *p = c->proto;
|
||||||
struct filter *filter = c->out_filter;
|
const struct filter *filter = c->out_filter;
|
||||||
struct proto_stats *stats = &c->stats;
|
struct proto_stats *stats = &c->stats;
|
||||||
rte *rt;
|
rte *rt;
|
||||||
int v;
|
int v;
|
||||||
@ -1362,7 +1362,7 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
|
|||||||
{
|
{
|
||||||
struct proto *p = c->proto;
|
struct proto *p = c->proto;
|
||||||
struct proto_stats *stats = &c->stats;
|
struct proto_stats *stats = &c->stats;
|
||||||
struct filter *filter = c->in_filter;
|
const struct filter *filter = c->in_filter;
|
||||||
rte *dummy = NULL;
|
rte *dummy = NULL;
|
||||||
net *nn;
|
net *nn;
|
||||||
|
|
||||||
@ -1503,7 +1503,7 @@ rte_modify(rte *old)
|
|||||||
|
|
||||||
/* Check rtable for best route to given net whether it would be exported do p */
|
/* Check rtable for best route to given net whether it would be exported do p */
|
||||||
int
|
int
|
||||||
rt_examine(rtable *t, net_addr *a, struct proto *p, struct filter *filter)
|
rt_examine(rtable *t, net_addr *a, struct proto *p, const struct filter *filter)
|
||||||
{
|
{
|
||||||
net *n = net_find(t, a);
|
net *n = net_find(t, a);
|
||||||
rte *rt = n ? n->routes : NULL;
|
rte *rt = n ? n->routes : NULL;
|
||||||
@ -2106,13 +2106,13 @@ rt_new_table(struct symbol *s, uint addr_type)
|
|||||||
{
|
{
|
||||||
/* Hack that allows to 'redefine' the master table */
|
/* Hack that allows to 'redefine' the master table */
|
||||||
if ((s->class == SYM_TABLE) &&
|
if ((s->class == SYM_TABLE) &&
|
||||||
(s->def == new_config->def_tables[addr_type]) &&
|
(s->table == new_config->def_tables[addr_type]) &&
|
||||||
((addr_type == NET_IP4) || (addr_type == NET_IP6)))
|
((addr_type == NET_IP4) || (addr_type == NET_IP6)))
|
||||||
return s->def;
|
return s->table;
|
||||||
|
|
||||||
struct rtable_config *c = cfg_allocz(sizeof(struct rtable_config));
|
struct rtable_config *c = cfg_allocz(sizeof(struct rtable_config));
|
||||||
|
|
||||||
cf_define_symbol(s, SYM_TABLE, c);
|
cf_define_symbol(s, SYM_TABLE, table, c);
|
||||||
c->name = s->name;
|
c->name = s->name;
|
||||||
c->addr_type = addr_type;
|
c->addr_type = addr_type;
|
||||||
c->gc_max_ops = 1000;
|
c->gc_max_ops = 1000;
|
||||||
@ -2171,7 +2171,7 @@ static struct rtable_config *
|
|||||||
rt_find_table_config(struct config *cf, char *name)
|
rt_find_table_config(struct config *cf, char *name)
|
||||||
{
|
{
|
||||||
struct symbol *sym = cf_find_symbol(cf, name);
|
struct symbol *sym = cf_find_symbol(cf, name);
|
||||||
return (sym && (sym->class == SYM_TABLE)) ? sym->def : NULL;
|
return (sym && (sym->class == SYM_TABLE)) ? sym->table : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,7 +23,7 @@ struct mrt_config {
|
|||||||
|
|
||||||
struct rtable_config *table_cf;
|
struct rtable_config *table_cf;
|
||||||
const char *table_expr;
|
const char *table_expr;
|
||||||
struct filter *filter;
|
const struct filter *filter;
|
||||||
const char *filename;
|
const char *filename;
|
||||||
uint period;
|
uint period;
|
||||||
int always_add_path;
|
int always_add_path;
|
||||||
@ -41,7 +41,7 @@ struct mrt_proto {
|
|||||||
struct mrt_dump_data {
|
struct mrt_dump_data {
|
||||||
const char *table_expr;
|
const char *table_expr;
|
||||||
struct rtable *table_ptr;
|
struct rtable *table_ptr;
|
||||||
struct filter *filter;
|
const struct filter *filter;
|
||||||
char *filename;
|
char *filename;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ struct mrt_table_dump_state {
|
|||||||
/* Configuration information */
|
/* Configuration information */
|
||||||
const char *table_expr; /* Wildcard for table name (or NULL) */
|
const char *table_expr; /* Wildcard for table name (or NULL) */
|
||||||
struct rtable *table_ptr; /* Explicit table (or NULL) */
|
struct rtable *table_ptr; /* Explicit table (or NULL) */
|
||||||
struct filter *filter; /* Optional filter */
|
const struct filter *filter; /* Optional filter */
|
||||||
const char *filename; /* Filename pattern */
|
const char *filename; /* Filename pattern */
|
||||||
int always_add_path; /* Always use *_ADDPATH message subtypes */
|
int always_add_path; /* Always use *_ADDPATH message subtypes */
|
||||||
|
|
||||||
|
@ -562,7 +562,7 @@ static struct rte *
|
|||||||
krt_export_net(struct krt_proto *p, net *net, rte **rt_free)
|
krt_export_net(struct krt_proto *p, net *net, rte **rt_free)
|
||||||
{
|
{
|
||||||
struct channel *c = p->p.main_channel;
|
struct channel *c = p->p.main_channel;
|
||||||
struct filter *filter = c->out_filter;
|
const struct filter *filter = c->out_filter;
|
||||||
rte *rt;
|
rte *rt;
|
||||||
|
|
||||||
if (c->ra_mode == RA_MERGED)
|
if (c->ra_mode == RA_MERGED)
|
||||||
|
@ -94,11 +94,9 @@ drop_gid(gid_t gid)
|
|||||||
static inline void
|
static inline void
|
||||||
add_num_const(char *name, int val)
|
add_num_const(char *name, int val)
|
||||||
{
|
{
|
||||||
struct symbol *s = cf_get_symbol(name);
|
struct f_val *v = cfg_alloc(sizeof(struct f_val));
|
||||||
s->class = SYM_CONSTANT | T_INT;
|
*v = (struct f_val) { .type = T_INT, .val.i = val };
|
||||||
s->def = cfg_allocz(sizeof(struct f_val));
|
cf_define_symbol(cf_get_symbol(name), SYM_CONSTANT | T_INT, val, v);
|
||||||
SYM_TYPE(s) = T_INT;
|
|
||||||
SYM_VAL(s).i = val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the code of read_iproute_table() is based on
|
/* the code of read_iproute_table() is based on
|
||||||
|
Loading…
Reference in New Issue
Block a user