mirror of
https://gitlab.labs.nic.cz/labs/bird.git
synced 2024-05-11 16:54:54 +00:00
Merge commit '17f91f9e6e70f7e3f29502e854823c0d48571eaa' into haugesund
This commit is contained in:
@@ -22,6 +22,13 @@ static inline u32 pair_b(u32 p) { return p & 0xFFFF; }
|
||||
#define f_generate_complex(fi_code, da, arg) \
|
||||
f_new_inst(FI_EA_SET, f_new_inst(fi_code, f_new_inst(FI_EA_GET, da), arg), da)
|
||||
|
||||
#define f_generate_complex_sym(fi_code, sym, arg) ({ \
|
||||
if (sym->class != SYM_ATTRIBUTE) \
|
||||
cf_error("Can't empty %s: not an attribute", sym->name); \
|
||||
f_generate_complex(fi_code, sym->attribute, arg); \
|
||||
})
|
||||
|
||||
|
||||
/*
|
||||
* Sets and their items are during parsing handled as lists, linked
|
||||
* through left ptr. The first item in a list also contains a pointer
|
||||
@@ -161,27 +168,31 @@ f_new_lc_item(u32 f1, u32 t1, u32 f2, u32 t2, u32 f3, u32 t3)
|
||||
}
|
||||
|
||||
static inline struct f_inst *
|
||||
f_generate_empty(struct f_dynamic_attr dyn)
|
||||
f_generate_empty(const struct symbol *sym)
|
||||
{
|
||||
const struct f_val *empty = f_get_empty(dyn.type);
|
||||
if (sym->class != SYM_ATTRIBUTE)
|
||||
cf_error("Can't empty %s: not an attribute", sym->name);
|
||||
|
||||
const struct ea_class *def = sym->attribute;
|
||||
const struct f_val *empty = f_get_empty(def->type);
|
||||
if (!empty)
|
||||
cf_error("Can't empty that attribute");
|
||||
cf_error("Can't empty attribute %s", def->name);
|
||||
|
||||
return f_new_inst(FI_EA_SET, f_new_inst(FI_CONSTANT, *empty), dyn);
|
||||
return f_new_inst(FI_EA_SET, f_new_inst(FI_CONSTANT, *empty), def);
|
||||
}
|
||||
|
||||
#define BA_AS_PATH 0x02
|
||||
|
||||
static inline struct f_inst *
|
||||
f_implicit_roa_check(struct rtable_config *tab)
|
||||
{
|
||||
struct f_dynamic_attr fda = f_new_dynamic_attr(T_PATH, EA_CODE(PROTOCOL_BGP, BA_AS_PATH));
|
||||
const struct ea_class *def = ea_class_find("bgp_path");
|
||||
if (!def)
|
||||
cf_error("Fatal: Couldn't find BGP path attribute definition.");
|
||||
|
||||
struct f_static_attr fsa = f_new_static_attr(T_NET, SA_NET, 1);
|
||||
|
||||
return f_new_inst(FI_ROA_CHECK,
|
||||
f_new_inst(FI_RTA_GET, fsa),
|
||||
f_new_inst(FI_AS_PATH_LAST, f_new_inst(FI_EA_GET, fda)),
|
||||
f_new_inst(FI_AS_PATH_LAST, f_new_inst(FI_EA_GET, def)),
|
||||
tab);
|
||||
}
|
||||
|
||||
@@ -293,8 +304,8 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
|
||||
|
||||
%type <xp> cmds_int cmd_prep
|
||||
%type <x> term block cmd cmds constant constructor print_list var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail
|
||||
%type <fda> dynamic_attr attr_bit
|
||||
%type <fsa> static_attr
|
||||
%type <fab> attr_bit
|
||||
%type <f> filter where_filter
|
||||
%type <fl> filter_body function_body
|
||||
%type <flv> lvalue
|
||||
@@ -335,7 +346,14 @@ filter_eval:
|
||||
|
||||
conf: custom_attr ;
|
||||
custom_attr: ATTRIBUTE type symbol ';' {
|
||||
cf_define_symbol($3, SYM_ATTRIBUTE, attribute, ca_lookup(new_config->pool, $3->name, $2)->fda);
|
||||
if (($3->class == SYM_ATTRIBUTE) && ($3->scope == new_config->root_scope))
|
||||
cf_error("Duplicate attribute %s definition", $3->name);
|
||||
|
||||
cf_define_symbol($3, SYM_ATTRIBUTE, attribute,
|
||||
ea_register_alloc(new_config->pool, (struct ea_class) {
|
||||
.name = $3->name,
|
||||
.type = $2,
|
||||
})->class);
|
||||
};
|
||||
|
||||
conf: bt_test_suite ;
|
||||
@@ -736,7 +754,7 @@ symbol_value: CF_SYM_KNOWN
|
||||
$$ = f_new_inst(FI_VAR_GET, $1);
|
||||
break;
|
||||
case SYM_ATTRIBUTE:
|
||||
$$ = f_new_inst(FI_EA_GET, *$1->attribute);
|
||||
$$ = f_new_inst(FI_EA_GET, $1->attribute);
|
||||
break;
|
||||
default:
|
||||
cf_error("Can't get value of symbol %s", $1->name);
|
||||
@@ -785,11 +803,9 @@ term:
|
||||
| constructor { $$ = $1; }
|
||||
|
||||
| static_attr { $$ = f_new_inst(FI_RTA_GET, $1); }
|
||||
|
||||
| dynamic_attr { $$ = f_new_inst(FI_EA_GET, $1); }
|
||||
| attr_bit {
|
||||
struct f_inst *c = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = (1U << $1.bit)});
|
||||
$$ = f_new_inst(FI_EQ, c, f_new_inst(FI_BITAND, f_new_inst(FI_EA_GET, $1), c));
|
||||
$$ = f_new_inst(FI_EQ, c, f_new_inst(FI_BITAND, f_new_inst(FI_EA_GET, $1.class), c));
|
||||
}
|
||||
|
||||
| term '.' IS_V4 { $$ = f_new_inst(FI_IS_V4, $1); }
|
||||
@@ -833,8 +849,6 @@ term:
|
||||
|
||||
| FORMAT '(' term ')' { $$ = f_new_inst(FI_FORMAT, $3); }
|
||||
|
||||
/* | term '.' LEN { $$->code = P('P','l'); } */
|
||||
|
||||
| function_call
|
||||
;
|
||||
|
||||
@@ -867,7 +881,9 @@ cmd:
|
||||
$$ = f_new_inst(FI_VAR_SET, $3, $1);
|
||||
break;
|
||||
case SYM_ATTRIBUTE:
|
||||
$$ = f_new_inst(FI_EA_SET, $3, *$1->attribute);
|
||||
if ($1->attribute->readonly)
|
||||
cf_error("Attribute %s is read-only", $1->attribute->name);
|
||||
$$ = f_new_inst(FI_EA_SET, $3, $1->attribute);
|
||||
break;
|
||||
default:
|
||||
cf_error("Can't assign to symbol %s", $1->name);
|
||||
@@ -877,22 +893,23 @@ cmd:
|
||||
DBG( "Ook, we'll return the value\n" );
|
||||
$$ = f_new_inst(FI_RETURN, $2);
|
||||
}
|
||||
| dynamic_attr '=' term ';' {
|
||||
$$ = f_new_inst(FI_EA_SET, $3, $1);
|
||||
}
|
||||
| static_attr '=' term ';' {
|
||||
if ($1.readonly)
|
||||
cf_error( "This static attribute is read-only.");
|
||||
$$ = f_new_inst(FI_RTA_SET, $3, $1);
|
||||
}
|
||||
| UNSET '(' dynamic_attr ')' ';' {
|
||||
$$ = f_new_inst(FI_EA_UNSET, $3);
|
||||
| UNSET '(' CF_SYM_KNOWN ')' ';' {
|
||||
if ($3->class != SYM_ATTRIBUTE)
|
||||
cf_error("Can't unset %s", $3->name);
|
||||
if ($3->attribute->readonly)
|
||||
cf_error("Attribute %s is read-only", $3->attribute->name);
|
||||
$$ = f_new_inst(FI_EA_UNSET, $3->attribute);
|
||||
}
|
||||
| attr_bit '=' term ';' {
|
||||
$$ = f_new_inst(FI_CONDITION, $3,
|
||||
f_generate_complex(FI_BITOR, $1,
|
||||
f_generate_complex(FI_BITOR, $1.class,
|
||||
f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = (1U << $1.bit)})),
|
||||
f_generate_complex(FI_BITAND, $1,
|
||||
f_generate_complex(FI_BITAND, $1.class,
|
||||
f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = ~(1U << $1.bit)}))
|
||||
);
|
||||
}
|
||||
@@ -919,11 +936,11 @@ cmd:
|
||||
$$ = f_new_inst(FI_SWITCH, $2, build_tree($4));
|
||||
}
|
||||
|
||||
| dynamic_attr '.' EMPTY ';' { $$ = f_generate_empty($1); }
|
||||
| dynamic_attr '.' PREPEND '(' term ')' ';' { $$ = f_generate_complex( FI_PATH_PREPEND, $1, $5 ); }
|
||||
| dynamic_attr '.' ADD '(' term ')' ';' { $$ = f_generate_complex( FI_CLIST_ADD, $1, $5 ); }
|
||||
| dynamic_attr '.' DELETE '(' term ')' ';' { $$ = f_generate_complex( FI_CLIST_DEL, $1, $5 ); }
|
||||
| dynamic_attr '.' FILTER '(' term ')' ';' { $$ = f_generate_complex( FI_CLIST_FILTER, $1, $5 ); }
|
||||
| CF_SYM_KNOWN '.' EMPTY ';' { $$ = f_generate_empty($1); }
|
||||
| CF_SYM_KNOWN '.' PREPEND '(' term ')' ';' { $$ = f_generate_complex_sym( FI_PATH_PREPEND, $1, $5 ); }
|
||||
| CF_SYM_KNOWN '.' ADD '(' term ')' ';' { $$ = f_generate_complex_sym( FI_CLIST_ADD, $1, $5 ); }
|
||||
| CF_SYM_KNOWN '.' DELETE '(' term ')' ';' { $$ = f_generate_complex_sym( FI_CLIST_DEL, $1, $5 ); }
|
||||
| CF_SYM_KNOWN '.' FILTER '(' term ')' ';' { $$ = f_generate_complex_sym( FI_CLIST_FILTER, $1, $5 ); }
|
||||
| BT_ASSERT '(' get_cf_position term get_cf_position ')' ';' { $$ = assert_done($4, $3 + 1, $5 - 1); }
|
||||
| BT_CHECK_ASSIGN '(' get_cf_position lvalue get_cf_position ',' term ')' ';' { $$ = assert_assign(&$4, $7, $3 + 1, $5 - 1); }
|
||||
;
|
||||
@@ -934,8 +951,17 @@ get_cf_position:
|
||||
};
|
||||
|
||||
lvalue:
|
||||
CF_SYM_KNOWN { cf_assert_symbol($1, SYM_VARIABLE); $$ = (struct f_lval) { .type = F_LVAL_VARIABLE, .sym = $1 }; }
|
||||
CF_SYM_KNOWN {
|
||||
switch ($1->class) {
|
||||
case SYM_VARIABLE_RANGE:
|
||||
$$ = (struct f_lval) { .type = F_LVAL_VARIABLE, .sym = $1 };
|
||||
break;
|
||||
case SYM_ATTRIBUTE:
|
||||
$$ = (struct f_lval) { .type = F_LVAL_EA, .da = $1->attribute };
|
||||
break;
|
||||
}
|
||||
}
|
||||
| static_attr { $$ = (struct f_lval) { .type = F_LVAL_SA, .sa = $1 }; }
|
||||
| dynamic_attr { $$ = (struct f_lval) { .type = F_LVAL_EA, .da = $1 }; };
|
||||
;
|
||||
|
||||
CF_END
|
||||
|
@@ -21,13 +21,6 @@ struct f_val {
|
||||
|
||||
#define fputip(a) ({ ip_addr *ax = falloc(sizeof(*ax)); *ax = (a); ax; })
|
||||
|
||||
/* Dynamic attribute definition (eattrs) */
|
||||
struct f_dynamic_attr {
|
||||
btype type; /* EA type (EAF_*) */
|
||||
u8 bit; /* For bitfield accessors */
|
||||
uint ea_code; /* EA code */
|
||||
};
|
||||
|
||||
enum f_sa_code {
|
||||
SA_FROM = 1,
|
||||
SA_GW,
|
||||
@@ -53,7 +46,6 @@ struct f_static_attr {
|
||||
/* Filter l-value type */
|
||||
enum f_lval_type {
|
||||
F_LVAL_VARIABLE,
|
||||
F_LVAL_PREFERENCE,
|
||||
F_LVAL_SA,
|
||||
F_LVAL_EA,
|
||||
};
|
||||
@@ -63,7 +55,7 @@ struct f_lval {
|
||||
enum f_lval_type type;
|
||||
union {
|
||||
struct symbol *sym;
|
||||
struct f_dynamic_attr da;
|
||||
const struct ea_class *da;
|
||||
struct f_static_attr sa;
|
||||
};
|
||||
};
|
||||
|
@@ -94,7 +94,7 @@ FID_DUMP_BODY()m4_dnl
|
||||
debug("%s" $4 "\n", INDENT, $5);
|
||||
]])
|
||||
FID_INTERPRET_EXEC()m4_dnl
|
||||
const $1 $2 = whati->$2
|
||||
$1 $2 = whati->$2
|
||||
FID_INTERPRET_BODY')
|
||||
|
||||
# Instruction arguments are needed only until linearization is done.
|
||||
@@ -256,7 +256,7 @@ FID_INTERPRET_BODY()')
|
||||
m4_define(SYMBOL, `FID_MEMBER(struct symbol *, sym, [[strcmp(f1->sym->name, f2->sym->name) || (f1->sym->class != f2->sym->class)]], "symbol %s", item->sym->name)')
|
||||
m4_define(RTC, `FID_MEMBER(struct rtable_config *, rtc, [[strcmp(f1->rtc->name, f2->rtc->name)]], "route table %s", item->rtc->name)')
|
||||
m4_define(STATIC_ATTR, `FID_MEMBER(struct f_static_attr, sa, f1->sa.sa_code != f2->sa.sa_code,,)')
|
||||
m4_define(DYNAMIC_ATTR, `FID_MEMBER(struct f_dynamic_attr, da, f1->da.ea_code != f2->da.ea_code,,)')
|
||||
m4_define(DYNAMIC_ATTR, `FID_MEMBER(const struct ea_class *, da, f1->da != f2->da,,)')
|
||||
m4_define(ACCESS_RTE, `FID_HIC(,[[do { if (!fs->rte) runtime("No route to access"); } while (0)]],NEVER_CONSTANT())')
|
||||
|
||||
# 2) Code wrapping
|
||||
|
@@ -662,14 +662,14 @@
|
||||
DYNAMIC_ATTR;
|
||||
ACCESS_RTE;
|
||||
ACCESS_EATTRS;
|
||||
RESULT_TYPE(da.type);
|
||||
RESULT_TYPE(da->type);
|
||||
{
|
||||
const struct f_val *empty;
|
||||
eattr *e = ea_find(*fs->eattrs, da.ea_code);
|
||||
const eattr *e = ea_find(*fs->eattrs, da->id);
|
||||
|
||||
if (e)
|
||||
{
|
||||
ASSERT_DIE(e->type == da.type);
|
||||
ASSERT_DIE(e->type == da->type);
|
||||
|
||||
switch (e->type) {
|
||||
case T_IP:
|
||||
@@ -682,7 +682,7 @@
|
||||
}]]);
|
||||
}
|
||||
}
|
||||
else if (empty = f_get_empty(da.type))
|
||||
else if (empty = f_get_empty(da->type))
|
||||
RESULT_VAL(*empty);
|
||||
else
|
||||
RESULT_VOID;
|
||||
@@ -694,16 +694,16 @@
|
||||
ACCESS_EATTRS;
|
||||
ARG_ANY(1);
|
||||
DYNAMIC_ATTR;
|
||||
ARG_TYPE(1, da.type);
|
||||
ARG_TYPE(1, da->type);
|
||||
{
|
||||
struct eattr *a;
|
||||
|
||||
if (da.type >= EAF_TYPE__MAX)
|
||||
if (da->type >= EAF_TYPE__MAX)
|
||||
bug("Unsupported attribute type");
|
||||
|
||||
f_rta_cow(fs);
|
||||
|
||||
switch (da.type) {
|
||||
switch (da->type) {
|
||||
case T_OPAQUE:
|
||||
case T_IFACE:
|
||||
runtime( "Setting opaque attribute is not allowed" );
|
||||
@@ -711,12 +711,12 @@
|
||||
|
||||
case T_IP:
|
||||
a = ea_set_attr(fs->eattrs,
|
||||
EA_LITERAL_STORE_ADATA(da.ea_code, da.type, 0, &v1.val.ip, sizeof(ip_addr)));
|
||||
EA_LITERAL_STORE_ADATA(da, 0, &v1.val.ip, sizeof(ip_addr)));
|
||||
break;
|
||||
|
||||
default:
|
||||
a = ea_set_attr(fs->eattrs,
|
||||
EA_LITERAL_GENERIC(da.ea_code, da.type, 0, .u = v1.val.bval));
|
||||
EA_LITERAL_GENERIC(da->id, da->type, 0, .u = v1.val.bval));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -731,7 +731,7 @@
|
||||
ACCESS_EATTRS;
|
||||
|
||||
f_rta_cow(fs);
|
||||
ea_unset_attr(fs->eattrs, 1, da.ea_code);
|
||||
ea_unset_attr(fs->eattrs, 1, da);
|
||||
}
|
||||
|
||||
INST(FI_LENGTH, 1, 1) { /* Get length of */
|
||||
|
@@ -87,15 +87,17 @@ void f_add_lines(const struct f_line_item *what, struct filter_iterator *fit);
|
||||
|
||||
|
||||
struct filter *f_new_where(struct f_inst *);
|
||||
static inline struct f_dynamic_attr f_new_dynamic_attr(u8 type, uint code)
|
||||
{ return (struct f_dynamic_attr) { .type = type, .ea_code = code }; }
|
||||
static inline struct f_dynamic_attr f_new_dynamic_attr_bit(u8 bit, uint code)
|
||||
{ return (struct f_dynamic_attr) { .type = T_INT, .bit = bit, .ea_code = code }; }
|
||||
static inline struct f_static_attr f_new_static_attr(btype type, int code, int readonly)
|
||||
{ return (struct f_static_attr) { .type = type, .sa_code = code, .readonly = readonly }; }
|
||||
struct f_inst *f_generate_complex(enum f_instruction_code fi_code, struct f_dynamic_attr da, struct f_inst *argument);
|
||||
struct f_inst *f_generate_roa_check(struct rtable_config *table, struct f_inst *prefix, struct f_inst *asn);
|
||||
|
||||
struct f_attr_bit {
|
||||
const struct ea_class *class;
|
||||
uint bit;
|
||||
};
|
||||
|
||||
#define f_new_dynamic_attr_bit(_bit, _name) ((struct f_attr_bit) { .bit = _bit, .class = ea_class_find(_name) })
|
||||
|
||||
/* Hook for call bt_assert() function in configuration */
|
||||
extern void (*bt_assert_hook)(int result, const struct f_line_item *assert);
|
||||
|
||||
|
128
filter/f-util.c
128
filter/f-util.c
@@ -2,7 +2,7 @@
|
||||
* Filters: utility functions
|
||||
*
|
||||
* Copyright 1998 Pavel Machek <pavel@ucw.cz>
|
||||
* 2017 Jan Maria Matejka <mq@ucw.cz>
|
||||
* 2017 Maria Matejka <mq@ucw.cz>
|
||||
*
|
||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||
*/
|
||||
@@ -40,129 +40,3 @@ struct filter *f_new_where(struct f_inst *where)
|
||||
f->root = f_linearize(cond);
|
||||
return f;
|
||||
}
|
||||
|
||||
#define CA_KEY(n) n->name, n->fda.type
|
||||
#define CA_NEXT(n) n->next
|
||||
#define CA_EQ(na,ta,nb,tb) (!strcmp(na,nb) && (ta == tb))
|
||||
#define CA_FN(n,t) (mem_hash(n, strlen(n)) ^ (t*0xaae99453U))
|
||||
#define CA_ORDER 8 /* Fixed */
|
||||
|
||||
struct ca_storage {
|
||||
struct ca_storage *next;
|
||||
struct f_dynamic_attr fda;
|
||||
u32 uc;
|
||||
char name[0];
|
||||
};
|
||||
|
||||
HASH(struct ca_storage) ca_hash;
|
||||
|
||||
static struct idm ca_idm;
|
||||
static struct ca_storage **ca_storage;
|
||||
static uint ca_storage_max;
|
||||
|
||||
static void
|
||||
ca_free(resource *r)
|
||||
{
|
||||
struct custom_attribute *ca = (void *) r;
|
||||
struct ca_storage *cas = HASH_FIND(ca_hash, CA, ca->name, ca->fda->type);
|
||||
ASSERT(cas);
|
||||
|
||||
ca->name = NULL;
|
||||
ca->fda = NULL;
|
||||
if (!--cas->uc) {
|
||||
uint id = EA_CUSTOM_ID(cas->fda.ea_code);
|
||||
idm_free(&ca_idm, id);
|
||||
HASH_REMOVE(ca_hash, CA, cas);
|
||||
ca_storage[id] = NULL;
|
||||
mb_free(cas);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ca_dump(resource *r)
|
||||
{
|
||||
struct custom_attribute *ca = (void *) r;
|
||||
debug("name \"%s\" id 0x%04x ea_type 0x%02x\n",
|
||||
ca->name, ca->fda->ea_code, ca->fda->type);
|
||||
}
|
||||
|
||||
static struct resclass ca_class = {
|
||||
.name = "Custom attribute",
|
||||
.size = sizeof(struct custom_attribute),
|
||||
.free = ca_free,
|
||||
.dump = ca_dump,
|
||||
.lookup = NULL,
|
||||
.memsize = NULL,
|
||||
};
|
||||
|
||||
struct custom_attribute *
|
||||
ca_lookup(pool *p, const char *name, btype type)
|
||||
{
|
||||
switch (type) {
|
||||
case T_INT:
|
||||
case T_IP:
|
||||
case T_QUAD:
|
||||
case T_PATH:
|
||||
case T_CLIST:
|
||||
case T_ECLIST:
|
||||
case T_LCLIST:
|
||||
break;
|
||||
default:
|
||||
cf_error("Custom route attribute of unsupported type");
|
||||
}
|
||||
|
||||
static int inited = 0;
|
||||
if (!inited) {
|
||||
idm_init(&ca_idm, &root_pool, 8);
|
||||
HASH_INIT(ca_hash, &root_pool, CA_ORDER);
|
||||
|
||||
ca_storage_max = 256;
|
||||
ca_storage = mb_allocz(&root_pool, sizeof(struct ca_storage *) * ca_storage_max);
|
||||
|
||||
inited++;
|
||||
}
|
||||
|
||||
struct ca_storage *cas = HASH_FIND(ca_hash, CA, name, type);
|
||||
if (cas) {
|
||||
cas->uc++;
|
||||
} else {
|
||||
|
||||
uint id = idm_alloc(&ca_idm);
|
||||
|
||||
if (id >= EA_CUSTOM_BIT)
|
||||
cf_error("Too many custom attributes.");
|
||||
|
||||
if (id >= ca_storage_max) {
|
||||
ca_storage_max *= 2;
|
||||
ca_storage = mb_realloc(ca_storage, sizeof(struct ca_storage *) * ca_storage_max * 2);
|
||||
}
|
||||
|
||||
cas = mb_allocz(&root_pool, sizeof(struct ca_storage) + strlen(name) + 1);
|
||||
cas->fda = f_new_dynamic_attr(type, EA_CUSTOM(id));
|
||||
cas->uc = 1;
|
||||
|
||||
strcpy(cas->name, name);
|
||||
ca_storage[id] = cas;
|
||||
|
||||
HASH_INSERT(ca_hash, CA, cas);
|
||||
}
|
||||
|
||||
struct custom_attribute *ca = ralloc(p, &ca_class);
|
||||
ca->fda = &(cas->fda);
|
||||
ca->name = cas->name;
|
||||
return ca;
|
||||
}
|
||||
|
||||
const char *
|
||||
ea_custom_name(uint ea)
|
||||
{
|
||||
uint id = EA_CUSTOM_ID(ea);
|
||||
if (id >= ca_storage_max)
|
||||
return NULL;
|
||||
|
||||
if (!ca_storage[id])
|
||||
return NULL;
|
||||
|
||||
return ca_storage[id]->name;
|
||||
}
|
||||
|
||||
|
@@ -70,13 +70,4 @@ void filters_dump_all(void);
|
||||
|
||||
#define FF_SILENT 2 /* Silent filter execution */
|
||||
|
||||
/* Custom route attributes */
|
||||
struct custom_attribute {
|
||||
resource r;
|
||||
struct f_dynamic_attr *fda;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct custom_attribute *ca_lookup(pool *p, const char *name, btype type);
|
||||
|
||||
#endif
|
||||
|
149
filter/test.conf
149
filter/test.conf
@@ -9,7 +9,109 @@ router id 62.168.0.1;
|
||||
/* We have to setup any protocol */
|
||||
protocol device { }
|
||||
|
||||
/* Setting some custom attributes, enough to force BIRD to reallocate the attribute idmap */
|
||||
attribute int test_ca_int1;
|
||||
attribute int test_ca_int2;
|
||||
attribute int test_ca_int3;
|
||||
attribute int test_ca_int4;
|
||||
attribute int test_ca_int5;
|
||||
attribute int test_ca_int6;
|
||||
attribute int test_ca_int7;
|
||||
attribute int test_ca_int8;
|
||||
attribute int test_ca_int9;
|
||||
attribute int test_ca_int10;
|
||||
|
||||
attribute ip test_ca_ip1;
|
||||
attribute ip test_ca_ip2;
|
||||
attribute ip test_ca_ip3;
|
||||
attribute ip test_ca_ip4;
|
||||
attribute ip test_ca_ip5;
|
||||
attribute ip test_ca_ip6;
|
||||
attribute ip test_ca_ip7;
|
||||
attribute ip test_ca_ip8;
|
||||
attribute ip test_ca_ip9;
|
||||
attribute ip test_ca_ip10;
|
||||
|
||||
attribute quad test_ca_quad1;
|
||||
attribute quad test_ca_quad2;
|
||||
attribute quad test_ca_quad3;
|
||||
attribute quad test_ca_quad4;
|
||||
attribute quad test_ca_quad5;
|
||||
attribute quad test_ca_quad6;
|
||||
attribute quad test_ca_quad7;
|
||||
attribute quad test_ca_quad8;
|
||||
attribute quad test_ca_quad9;
|
||||
attribute quad test_ca_quad10;
|
||||
|
||||
attribute bgppath test_ca_bgppath1;
|
||||
attribute bgppath test_ca_bgppath2;
|
||||
attribute bgppath test_ca_bgppath3;
|
||||
attribute bgppath test_ca_bgppath4;
|
||||
attribute bgppath test_ca_bgppath5;
|
||||
attribute bgppath test_ca_bgppath6;
|
||||
attribute bgppath test_ca_bgppath7;
|
||||
attribute bgppath test_ca_bgppath8;
|
||||
attribute bgppath test_ca_bgppath9;
|
||||
attribute bgppath test_ca_bgppath10;
|
||||
|
||||
attribute clist test_ca_clist1;
|
||||
attribute clist test_ca_clist2;
|
||||
attribute clist test_ca_clist3;
|
||||
attribute clist test_ca_clist4;
|
||||
attribute clist test_ca_clist5;
|
||||
attribute clist test_ca_clist6;
|
||||
attribute clist test_ca_clist7;
|
||||
attribute clist test_ca_clist8;
|
||||
attribute clist test_ca_clist9;
|
||||
attribute clist test_ca_clist10;
|
||||
|
||||
attribute eclist test_ca_eclist1;
|
||||
attribute eclist test_ca_eclist2;
|
||||
attribute eclist test_ca_eclist3;
|
||||
attribute eclist test_ca_eclist4;
|
||||
attribute eclist test_ca_eclist5;
|
||||
attribute eclist test_ca_eclist6;
|
||||
attribute eclist test_ca_eclist7;
|
||||
attribute eclist test_ca_eclist8;
|
||||
attribute eclist test_ca_eclist9;
|
||||
attribute eclist test_ca_eclist10;
|
||||
|
||||
attribute lclist test_ca_lclist1;
|
||||
attribute lclist test_ca_lclist2;
|
||||
attribute lclist test_ca_lclist3;
|
||||
attribute lclist test_ca_lclist4;
|
||||
attribute lclist test_ca_lclist5;
|
||||
attribute lclist test_ca_lclist6;
|
||||
attribute lclist test_ca_lclist7;
|
||||
attribute lclist test_ca_lclist8;
|
||||
attribute lclist test_ca_lclist9;
|
||||
attribute lclist test_ca_lclist10;
|
||||
|
||||
attribute lclist test_ca_lclist_max1;
|
||||
attribute lclist test_ca_lclist_max2;
|
||||
attribute lclist test_ca_lclist_max3;
|
||||
attribute lclist test_ca_lclist_max4;
|
||||
attribute lclist test_ca_lclist_max5;
|
||||
attribute lclist test_ca_lclist_max6;
|
||||
attribute lclist test_ca_lclist_max7;
|
||||
attribute lclist test_ca_lclist_max8;
|
||||
attribute lclist test_ca_lclist_max9;
|
||||
attribute lclist test_ca_lclist_max10;
|
||||
attribute lclist test_ca_lclist_max11;
|
||||
attribute lclist test_ca_lclist_max12;
|
||||
attribute lclist test_ca_lclist_max13;
|
||||
attribute lclist test_ca_lclist_max14;
|
||||
attribute lclist test_ca_lclist_max15;
|
||||
attribute lclist test_ca_lclist_max16;
|
||||
attribute lclist test_ca_lclist_max17;
|
||||
attribute lclist test_ca_lclist_max18;
|
||||
attribute lclist test_ca_lclist_max19;
|
||||
attribute lclist test_ca_lclist_max20;
|
||||
attribute lclist test_ca_lclist_max21;
|
||||
|
||||
|
||||
/* Uncomment this to get an error */
|
||||
#attribute int bgp_path;
|
||||
|
||||
/*
|
||||
* Common definitions and functions
|
||||
@@ -1331,6 +1433,7 @@ function __test2()
|
||||
|
||||
filter testf
|
||||
int j;
|
||||
bool t;
|
||||
{
|
||||
print "Heya, filtering route to ", net.ip, " prefixlen ", net.len, " source ", source;
|
||||
print "This route was from ", from;
|
||||
@@ -1342,6 +1445,52 @@ int j;
|
||||
rip_metric = 14;
|
||||
unset(rip_metric);
|
||||
|
||||
test_ca_int1 = 42;
|
||||
test_ca_ip2 = 1.3.5.7;
|
||||
test_ca_quad3 = 2.4.6.8;
|
||||
test_ca_bgppath4 = +empty+;
|
||||
test_ca_clist5 = -empty-;
|
||||
test_ca_eclist6 = --empty--;
|
||||
test_ca_lclist7 = ---empty---;
|
||||
|
||||
igp_metric = 53;
|
||||
babel_metric = 64;
|
||||
t = defined(babel_router_id);
|
||||
j = babel_seqno;
|
||||
|
||||
bgp_origin = ORIGIN_IGP;
|
||||
bgp_path = +empty+;
|
||||
bgp_next_hop = 3456:789a:bcde:f012::3456:789a;
|
||||
bgp_med = 71;
|
||||
bgp_local_pref = 942;
|
||||
t = defined(bgp_atomic_aggr);
|
||||
t = defined(bgp_aggregator);
|
||||
bgp_community = -empty-;
|
||||
bgp_originator_id = 9.7.5.3;
|
||||
bgp_cluster_list = -empty-;
|
||||
t = defined(bgp_mp_reach_nlri);
|
||||
t = defined(bgp_mp_unreach_nlri);
|
||||
bgp_ext_community = --empty--;
|
||||
bgp_as4_path = +empty+;
|
||||
t = defined(bgp_as4_aggregator);
|
||||
t = defined(bgp_aigp);
|
||||
bgp_large_community = ---empty---;
|
||||
t = defined(bgp_mpls_label_stack);
|
||||
|
||||
ospf_metric1 = 64;
|
||||
ospf_metric2 = 111;
|
||||
ospf_tag = 654432;
|
||||
|
||||
radv_preference = RA_PREF_LOW;
|
||||
radv_lifetime = 28;
|
||||
|
||||
rip_metric = 2;
|
||||
rip_tag = 4;
|
||||
t = defined(rip_from);
|
||||
|
||||
krt_source = 17;
|
||||
krt_metric = 19;
|
||||
|
||||
# krt_lock_mtu = false;
|
||||
# krt_lock_window = true;
|
||||
# krt_lock_rtt = krt_lock_rttvar && krt_lock_sstresh || krt_lock_cwnd;
|
||||
|
Reference in New Issue
Block a user