mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-08 12:18:42 +00:00
Filter: any lvalue can get its methods called
This commit is contained in:
parent
ae8ecafda9
commit
5951dfbd5e
@ -1604,7 +1604,8 @@ in the foot).
|
||||
|
||||
Statement <cf><m/P/ = prepend(<m/P/, <m/A/);</cf> can be shortened to
|
||||
<cf><m/P/.prepend(<m/A/);</cf> if <m/P/ is appropriate route attribute
|
||||
(for example <cf/bgp_path/). Similarly for <cf/delete/ and <cf/filter/.
|
||||
(for example <cf/bgp_path/) or a local variable.
|
||||
Similarly for <cf/delete/ and <cf/filter/.
|
||||
|
||||
<tag><label id="type-bgpmask">bgpmask</tag>
|
||||
BGP masks are patterns used for BGP path matching (using <cf>path
|
||||
@ -1653,7 +1654,8 @@ in the foot).
|
||||
|
||||
Statement <cf><m/C/ = add(<m/C/, <m/P/);</cf> can be shortened to
|
||||
<cf><m/C/.add(<m/P/);</cf> if <m/C/ is appropriate route attribute (for
|
||||
example <cf/bgp_community/). Similarly for <cf/delete/ and <cf/filter/.
|
||||
example <cf/bgp_community/) or a local variable.
|
||||
Similarly for <cf/delete/ and <cf/filter/.
|
||||
|
||||
<cf><m/C/.min</cf> returns the minimum element of clist <m/C/.
|
||||
|
||||
|
@ -292,28 +292,35 @@ assert_done(struct f_inst *expr, const char *start, const char *end)
|
||||
: "???");
|
||||
}
|
||||
|
||||
static struct f_inst *
|
||||
f_lval_getter(struct f_lval *lval)
|
||||
{
|
||||
switch (lval->type) {
|
||||
case F_LVAL_VARIABLE: return f_new_inst(FI_VAR_GET, lval->sym);
|
||||
case F_LVAL_SA: return f_new_inst(FI_RTA_GET, lval->sa);
|
||||
case F_LVAL_EA: return f_new_inst(FI_EA_GET, lval->da);
|
||||
default: bug("Unknown lval type");
|
||||
}
|
||||
}
|
||||
|
||||
static struct f_inst *
|
||||
f_lval_setter(struct f_lval *lval, struct f_inst *expr)
|
||||
{
|
||||
switch (lval->type) {
|
||||
case F_LVAL_VARIABLE: return f_new_inst(FI_VAR_SET, expr, lval->sym);
|
||||
case F_LVAL_SA: return f_new_inst(FI_RTA_SET, expr, lval->sa);
|
||||
case F_LVAL_EA: return f_new_inst(FI_EA_SET, expr, lval->da);
|
||||
default: bug("Unknown lval type");
|
||||
}
|
||||
}
|
||||
|
||||
static struct f_inst *
|
||||
assert_assign(struct f_lval *lval, struct f_inst *expr, const char *start, const char *end)
|
||||
{
|
||||
struct f_inst *setter, *getter, *checker;
|
||||
switch (lval->type) {
|
||||
case F_LVAL_VARIABLE:
|
||||
setter = f_new_inst(FI_VAR_SET, expr, lval->sym);
|
||||
getter = f_new_inst(FI_VAR_GET, lval->sym);
|
||||
break;
|
||||
case F_LVAL_SA:
|
||||
setter = f_new_inst(FI_RTA_SET, expr, lval->sa);
|
||||
getter = f_new_inst(FI_RTA_GET, lval->sa);
|
||||
break;
|
||||
case F_LVAL_EA:
|
||||
setter = f_new_inst(FI_EA_SET, expr, lval->da);
|
||||
getter = f_new_inst(FI_EA_GET, lval->da);
|
||||
break;
|
||||
default:
|
||||
bug("Unknown lval type");
|
||||
}
|
||||
struct f_inst *setter = f_lval_setter(lval, expr),
|
||||
*getter = f_lval_getter(lval);
|
||||
|
||||
checker = f_new_inst(FI_EQ, expr, getter);
|
||||
struct f_inst *checker = f_new_inst(FI_EQ, expr, getter);
|
||||
setter->next = checker;
|
||||
|
||||
return assert_done(setter, start, end);
|
||||
@ -1014,11 +1021,11 @@ cmd:
|
||||
$$ = f_new_inst(FI_SWITCH, $2, $4);
|
||||
}
|
||||
|
||||
| dynamic_attr '.' {
|
||||
f_push_method_scope(f_new_inst(FI_EA_GET, $1));
|
||||
| lvalue '.' {
|
||||
f_push_method_scope(f_lval_getter(&$1));
|
||||
} method_cmd ';' {
|
||||
f_pop_method_scope();
|
||||
$$ = f_new_inst(FI_EA_SET, $4, $1);
|
||||
$$ = f_lval_setter(&$1, $4);
|
||||
}
|
||||
| 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); }
|
||||
@ -1030,7 +1037,19 @@ 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;
|
||||
default:
|
||||
cf_error("Variable name or custom attribute name required");
|
||||
}
|
||||
}
|
||||
| static_attr { $$ = (struct f_lval) { .type = F_LVAL_SA, .sa = $1 }; }
|
||||
| dynamic_attr { $$ = (struct f_lval) { .type = F_LVAL_EA, .da = $1 }; };
|
||||
|
||||
|
@ -9,6 +9,8 @@ router id 62.168.0.1;
|
||||
/* We have to setup any protocol */
|
||||
protocol device { }
|
||||
|
||||
attribute bgppath mypath;
|
||||
attribute lclist mylclist;
|
||||
|
||||
|
||||
/*
|
||||
@ -1694,6 +1696,15 @@ filter vpn_filter
|
||||
bgp_ext_community.add((ro, 135, 999));
|
||||
bgp_large_community.add((6464156, 89646354, 8675643));
|
||||
|
||||
mypath.prepend(65533);
|
||||
mylclist.add((1234, 5678, 90123));
|
||||
|
||||
bgppath locpath;
|
||||
lclist loclclist;
|
||||
|
||||
locpath.prepend(65533);
|
||||
loclclist.add((1234, 5678, 90123));
|
||||
|
||||
accept;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user