mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Filter: Fixes and improvements related to case/sets
Unify grammar for set_atom and switch_atom to avoid inconsistencies between them. Fix errors in documentation related to case statement and set type. Change 'vpnrd' to 'rd' to be consistent with the filter language. Thanks to Mikhail Mayorov for bugreport.
This commit is contained in:
parent
163ab3130f
commit
39e75b879b
@ -1650,7 +1650,7 @@ in the foot).
|
|||||||
Route Distinguisher (<rfc id="4364">). They support the same special
|
Route Distinguisher (<rfc id="4364">). They support the same special
|
||||||
operators as IP prefixes, and also <cf/.rd/ which extracts the Route
|
operators as IP prefixes, and also <cf/.rd/ which extracts the Route
|
||||||
Distinguisher. Their literals are written
|
Distinguisher. Their literals are written
|
||||||
as <cf><m/vpnrd/ <m/ipprefix/</cf>
|
as <cf><m/rd/ <m/ipprefix/</cf>
|
||||||
|
|
||||||
<cf/NET_ROA4/ and <cf/NET_ROA6/ prefixes hold an IP prefix range
|
<cf/NET_ROA4/ and <cf/NET_ROA6/ prefixes hold an IP prefix range
|
||||||
together with an ASN. They support the same special operators as IP
|
together with an ASN. They support the same special operators as IP
|
||||||
@ -1665,9 +1665,9 @@ in the foot).
|
|||||||
<cf/NET_MPLS/ holds a single MPLS label and its handling is currently
|
<cf/NET_MPLS/ holds a single MPLS label and its handling is currently
|
||||||
not implemented.
|
not implemented.
|
||||||
|
|
||||||
<tag><label id="type-vpnrd">vpnrd</tag>
|
<tag><label id="type-rd"><label id="type-vpnrd">rd</tag>
|
||||||
This is a route distinguisher according to <rfc id="4364">. There are
|
This is a route distinguisher according to <rfc id="4364">. There are
|
||||||
three kinds of RD's: <cf><m/asn/:<m/32bit int/</cf>, <cf><m/asn4/:<m/16bit int/</cf>
|
three kinds of RDs: <cf><m/asn/:<m/32bit int/</cf>, <cf><m/asn4/:<m/16bit int/</cf>
|
||||||
and <cf><m/IPv4 address/:<m/32bit int/</cf>
|
and <cf><m/IPv4 address/:<m/32bit int/</cf>
|
||||||
|
|
||||||
<tag><label id="type-ec">ec</tag>
|
<tag><label id="type-ec">ec</tag>
|
||||||
@ -1694,9 +1694,9 @@ in the foot).
|
|||||||
to extract corresponding components of LCs:
|
to extract corresponding components of LCs:
|
||||||
<cf>(<m/asn/, <m/data1/, <m/data2/)</cf>.
|
<cf>(<m/asn/, <m/data1/, <m/data2/)</cf>.
|
||||||
|
|
||||||
<tag><label id="type-set">int|pair|quad|ip|prefix|ec|lc|enum set</tag>
|
<tag><label id="type-set">int|pair|quad|ip|prefix|ec|lc|rd|enum set</tag>
|
||||||
Filters recognize four types of sets. Sets are similar to strings: you
|
Filters recognize several types of sets. Sets are similar to strings: you
|
||||||
can pass them around but you can't modify them. Literals of type <cf>int
|
can pass them around but you cannot modify them. Literals of type <cf>int
|
||||||
set</cf> look like <cf> [ 1, 2, 5..7 ]</cf>. As you can see, both simple
|
set</cf> look like <cf> [ 1, 2, 5..7 ]</cf>. As you can see, both simple
|
||||||
values and ranges are permitted in sets.
|
values and ranges are permitted in sets.
|
||||||
|
|
||||||
@ -1719,9 +1719,11 @@ in the foot).
|
|||||||
is valid, while <cf/(10, *, 20..30)/ or <cf/(10, 20..30, 40)/ is not
|
is valid, while <cf/(10, *, 20..30)/ or <cf/(10, 20..30, 40)/ is not
|
||||||
valid.
|
valid.
|
||||||
|
|
||||||
You can also use expressions for int, pair, EC and LC set values.
|
You can also use named constants or compound expressions for non-prefix
|
||||||
However, it must be possible to evaluate these expressions before daemon
|
set values. However, it must be possible to evaluate these expressions
|
||||||
boots. So you can use only constants inside them. E.g.
|
before daemon boots. So you can use only constants inside them. Also,
|
||||||
|
in case of compound expressions, they require parentheses around them.
|
||||||
|
E.g.
|
||||||
|
|
||||||
<code>
|
<code>
|
||||||
define one=1;
|
define one=1;
|
||||||
@ -1730,7 +1732,7 @@ in the foot).
|
|||||||
pair set ps;
|
pair set ps;
|
||||||
ec set es;
|
ec set es;
|
||||||
|
|
||||||
odds = [ one, 2+1, 6-one, 2*2*2-1, 9, 11 ];
|
odds = [ one, (2+1), (6-one), (2*2*2-1), 9, 11 ];
|
||||||
ps = [ (1,one+one), (3,4)..(4,8), (5,*), (6,3..6), (7..9,*) ];
|
ps = [ (1,one+one), (3,4)..(4,8), (5,*), (6,3..6), (7..9,*) ];
|
||||||
es = [ (rt, myas, 3*10), (rt, myas+one, 0..16*16*16-1), (ro, myas+2, *) ];
|
es = [ (rt, myas, 3*10), (rt, myas+one, 0..16*16*16-1), (ro, myas+2, *) ];
|
||||||
</code>
|
</code>
|
||||||
@ -1943,13 +1945,16 @@ may be an existing one (when just name is used) or a locally defined (when type
|
|||||||
and name is used). In both cases, it must have the same type as elements.
|
and name is used). In both cases, it must have the same type as elements.
|
||||||
|
|
||||||
<p>The <cf>case</cf> is similar to case from Pascal. Syntax is <cf>case
|
<p>The <cf>case</cf> is similar to case from Pascal. Syntax is <cf>case
|
||||||
<m/expr/ { else: | <m/num_or_prefix [ .. num_or_prefix]/: <m/statement/ ; [
|
<m/expr/ { else: | <m/set_body_expr/ /: <m/statement/ ; [... ] }</cf>.
|
||||||
... ] }</cf>. The expression after <cf>case</cf> can be of any type which can be
|
|
||||||
on the left side of the ˜ operator and anything that could be a member of
|
The expression after <cf>case</cf> can be of any type that could be a member of
|
||||||
a set is allowed before <cf/:/. Multiple commands are allowed without <cf/{}/
|
a set, while the <m/set_body_expr/ before <cf/:/ can be anything (constants,
|
||||||
grouping. If <cf><m/expr/</cf> matches one of the <cf/:/ clauses, statements
|
intervals, expressions) that could be a part of a set literal. One exception is
|
||||||
between it and next <cf/:/ statement are executed. If <cf><m/expr/</cf> matches
|
prefix type, which can be used in sets bud not in <cf/case/ structure. Multiple
|
||||||
neither of the <cf/:/ clauses, the statements after <cf/else:/ are executed.
|
commands are allowed without <cf/{}/ grouping. If <cf><m/expr/</cf> matches one
|
||||||
|
of the <cf/:/ clauses, statements between it and next <cf/:/ statement are
|
||||||
|
executed. If <cf><m/expr/</cf> matches neither of the <cf/:/ clauses, the
|
||||||
|
statements after <cf/else:/ are executed.
|
||||||
|
|
||||||
<p>Here is example that uses <cf/if/ and <cf/case/ structures:
|
<p>Here is example that uses <cf/if/ and <cf/case/ structures:
|
||||||
|
|
||||||
@ -4085,11 +4090,11 @@ could have up to 5 channels: <cf/ipv4/, <cf/ipv6/, <cf/vpn4/, <cf/vpn6/, and
|
|||||||
<cf/mpls/.
|
<cf/mpls/.
|
||||||
|
|
||||||
<p><descrip>
|
<p><descrip>
|
||||||
<tag><label id="l3vpn-route-distinguisher">route distinguisher <m/vpnrd/</tag>
|
<tag><label id="l3vpn-route-distinguisher">route distinguisher <m/rd/</tag>
|
||||||
The route distinguisher that is attached to routes in the export
|
The route distinguisher that is attached to routes in the export
|
||||||
direction. Mandatory.
|
direction. Mandatory.
|
||||||
|
|
||||||
<tag><label id="l3vpn-rd">rd <m/vpnrd/</tag>
|
<tag><label id="l3vpn-rd">rd <m/rd/</tag>
|
||||||
A shorthand for the option <cf/route distinguisher/.
|
A shorthand for the option <cf/route distinguisher/.
|
||||||
|
|
||||||
<tag><label id="l3vpn-import-target">import target <m/ec/|<m/ec-set/</tag>
|
<tag><label id="l3vpn-import-target">import target <m/ec/|<m/ec-set/</tag>
|
||||||
|
@ -390,7 +390,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
|
|||||||
%type <i32> cnum
|
%type <i32> cnum
|
||||||
%type <e> pair_item ec_item lc_item set_item switch_item ec_items set_items switch_items switch_body
|
%type <e> pair_item ec_item lc_item set_item switch_item ec_items set_items switch_items switch_body
|
||||||
%type <trie> fprefix_set
|
%type <trie> fprefix_set
|
||||||
%type <v> set_atom switch_atom fipa
|
%type <v> set_atom0 set_atom switch_atom fipa
|
||||||
%type <px> fprefix
|
%type <px> fprefix
|
||||||
%type <t> get_cf_position
|
%type <t> get_cf_position
|
||||||
%type <s> for_var
|
%type <s> for_var
|
||||||
@ -636,27 +636,30 @@ fipa:
|
|||||||
* as a function call in switch case cmds.
|
* as a function call in switch case cmds.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
set_atom:
|
set_atom0:
|
||||||
NUM { $$.type = T_INT; $$.val.i = $1; }
|
NUM { $$.type = T_INT; $$.val.i = $1; }
|
||||||
| fipa { $$ = $1; }
|
| fipa { $$ = $1; }
|
||||||
| VPN_RD { $$.type = T_RD; $$.val.ec = $1; }
|
| VPN_RD { $$.type = T_RD; $$.val.ec = $1; }
|
||||||
| ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); }
|
| ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); }
|
||||||
| '(' term ')' {
|
| '(' term ')' {
|
||||||
$$ = cf_eval($2, T_VOID);
|
$$ = cf_eval($2, T_VOID);
|
||||||
if (!f_valid_set_type($$.type)) cf_error("Set-incompatible type");
|
if (!f_valid_set_type($$.type))
|
||||||
|
cf_error("Set-incompatible type (%s)", f_type_name($$.type));
|
||||||
}
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
set_atom:
|
||||||
|
set_atom0
|
||||||
| symbol_known {
|
| symbol_known {
|
||||||
cf_assert_symbol($1, SYM_CONSTANT);
|
cf_assert_symbol($1, 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 (%s)", $1->name, f_type_name(SYM_TYPE($1)));
|
||||||
$$ = *$1->val;
|
$$ = *$1->val;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
switch_atom:
|
switch_atom:
|
||||||
NUM { $$.type = T_INT; $$.val.i = $1; }
|
set_atom0
|
||||||
| '(' term ')' { $$ = cf_eval($2, T_INT); }
|
|
||||||
| fipa { $$ = $1; }
|
|
||||||
| ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
cnum:
|
cnum:
|
||||||
@ -749,7 +752,7 @@ fprefix_set:
|
|||||||
;
|
;
|
||||||
|
|
||||||
switch_body: /* EMPTY */ { $$ = NULL; }
|
switch_body: /* EMPTY */ { $$ = NULL; }
|
||||||
| switch_body switch_items ':' cmds_scoped {
|
| switch_body switch_items ':' cmds_scoped {
|
||||||
/* Fill data fields */
|
/* Fill data fields */
|
||||||
struct f_tree *t;
|
struct f_tree *t;
|
||||||
for (t = $2; t; t = t->left)
|
for (t = $2; t; t = t->left)
|
||||||
|
@ -138,7 +138,7 @@ function t_int()
|
|||||||
}
|
}
|
||||||
|
|
||||||
case four {
|
case four {
|
||||||
4: bt_assert(true);
|
(2+2): bt_assert(true);
|
||||||
else: bt_assert(false);
|
else: bt_assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user