diff options
author | Maria Matejka <mq@ucw.cz> | 2022-05-30 16:59:24 +0200 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2022-05-30 16:59:24 +0200 |
commit | 5051e3c4afe04aeb59abeaa3370c9e660dfa37f1 (patch) | |
tree | ed70693701387b10d87710199b7770ae7153c23b /filter | |
parent | c1645b9d5bef3d08ef91ac21197a4860a490bfd4 (diff) | |
parent | 17f91f9e6e70f7e3f29502e854823c0d48571eaa (diff) |
Merge commit '17f91f9e6e70f7e3f29502e854823c0d48571eaa' into haugesund
Diffstat (limited to 'filter')
-rw-r--r-- | filter/config.Y | 88 | ||||
-rw-r--r-- | filter/data.h | 10 | ||||
-rw-r--r-- | filter/decl.m4 | 4 | ||||
-rw-r--r-- | filter/f-inst.c | 20 | ||||
-rw-r--r-- | filter/f-inst.h | 12 | ||||
-rw-r--r-- | filter/f-util.c | 128 | ||||
-rw-r--r-- | filter/filter.h | 9 | ||||
-rw-r--r-- | filter/test.conf | 151 |
8 files changed, 228 insertions, 194 deletions
diff --git a/filter/config.Y b/filter/config.Y index 92656f7c..f21f1c8e 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -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 diff --git a/filter/data.h b/filter/data.h index cba47d6a..4d2622ab 100644 --- a/filter/data.h +++ b/filter/data.h @@ -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; }; }; diff --git a/filter/decl.m4 b/filter/decl.m4 index 2e4fb235..c59cd7f3 100644 --- a/filter/decl.m4 +++ b/filter/decl.m4 @@ -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 diff --git a/filter/f-inst.c b/filter/f-inst.c index 73a57473..5d78c98e 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -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 */ diff --git a/filter/f-inst.h b/filter/f-inst.h index 32da4653..047a66c9 100644 --- a/filter/f-inst.h +++ b/filter/f-inst.h @@ -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); diff --git a/filter/f-util.c b/filter/f-util.c index 83ae01f6..fb93ee80 100644 --- a/filter/f-util.c +++ b/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; -} - diff --git a/filter/filter.h b/filter/filter.h index 0c3486e0..3f2e62eb 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -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 diff --git a/filter/test.conf b/filter/test.conf index 062756b1..21e7330f 100644 --- a/filter/test.conf +++ b/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; |