mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Adds filter clist operation.
This commit is contained in:
parent
35f8c731ea
commit
e08d2ff08e
@ -849,10 +849,15 @@ incompatible with each other (that is to prevent you from shooting in the foot).
|
|||||||
operator deletes all items from clist <m/C/ that are also
|
operator deletes all items from clist <m/C/ that are also
|
||||||
members of set <m/P/.
|
members of set <m/P/.
|
||||||
|
|
||||||
Statement <cf><m/C/ = add(<m/C/, <m/P/);</cf> can be shortened to
|
<cf>filter(<m/C/,<m/P/)</cf> deletes all items from clist
|
||||||
<cf><m/C/.add(<m/P/);</cf> if <m/C/ is appropriate route attribute
|
<m/C/ that are not members of pair (or quad) set <m/P/.
|
||||||
(for example <cf/bgp_community/). Similarly for <cf/delete/.
|
I.e., <cf/filter/ do the same as <cf/delete/ with inverted
|
||||||
|
set <m/P/.
|
||||||
|
|
||||||
|
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/.
|
||||||
</descrip>
|
</descrip>
|
||||||
|
|
||||||
<sect>Operators
|
<sect>Operators
|
||||||
|
@ -566,6 +566,7 @@ term:
|
|||||||
| PREPEND '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('A','p'); $$->a1.p = $3; $$->a2.p = $5; }
|
| PREPEND '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('A','p'); $$->a1.p = $3; $$->a2.p = $5; }
|
||||||
| ADD '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'a'; }
|
| ADD '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'a'; }
|
||||||
| DELETE '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'd'; }
|
| DELETE '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'd'; }
|
||||||
|
| FILTER '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'f'; }
|
||||||
|
|
||||||
/* | term '.' LEN { $$->code = P('P','l'); } */
|
/* | term '.' LEN { $$->code = P('P','l'); } */
|
||||||
|
|
||||||
@ -706,6 +707,7 @@ cmd:
|
|||||||
| rtadot dynamic_attr '.' PREPEND '(' term ')' ';' { $$ = f_generate_complex( P('A','p'), 'x', $2, $6 ); }
|
| rtadot dynamic_attr '.' PREPEND '(' term ')' ';' { $$ = f_generate_complex( P('A','p'), 'x', $2, $6 ); }
|
||||||
| rtadot dynamic_attr '.' ADD '(' term ')' ';' { $$ = f_generate_complex( P('C','a'), 'a', $2, $6 ); }
|
| rtadot dynamic_attr '.' ADD '(' term ')' ';' { $$ = f_generate_complex( P('C','a'), 'a', $2, $6 ); }
|
||||||
| rtadot dynamic_attr '.' DELETE '(' term ')' ';' { $$ = f_generate_complex( P('C','a'), 'd', $2, $6 ); }
|
| rtadot dynamic_attr '.' DELETE '(' term ')' ';' { $$ = f_generate_complex( P('C','a'), 'd', $2, $6 ); }
|
||||||
|
| rtadot dynamic_attr '.' FILTER '(' term ')' ';' { $$ = f_generate_complex( P('C','a'), 'f', $2, $6 ); }
|
||||||
;
|
;
|
||||||
|
|
||||||
CF_END
|
CF_END
|
||||||
|
@ -279,7 +279,7 @@ clist_match_set(struct adata *clist, struct f_tree *set)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct adata *
|
static struct adata *
|
||||||
clist_del_matching(struct linpool *pool, struct adata *clist, struct f_tree *set)
|
clist_filter(struct linpool *pool, struct adata *clist, struct f_tree *set, int pos)
|
||||||
{
|
{
|
||||||
if (!clist)
|
if (!clist)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -294,7 +294,7 @@ clist_del_matching(struct linpool *pool, struct adata *clist, struct f_tree *set
|
|||||||
|
|
||||||
while (l < end) {
|
while (l < end) {
|
||||||
v.val.i = *l++;
|
v.val.i = *l++;
|
||||||
if (!find_tree(set, v))
|
if (pos == !!find_tree(set, v)) /* pos && find_tree || !pos && !find_tree */
|
||||||
*k++ = v.val.i;
|
*k++ = v.val.i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -945,7 +945,7 @@ interpret(struct f_inst *what)
|
|||||||
runtime("Can't add/delete to non-clist");
|
runtime("Can't add/delete to non-clist");
|
||||||
|
|
||||||
struct f_val dummy;
|
struct f_val dummy;
|
||||||
u16 op = what->aux;
|
int arg_set = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
if ((v2.type == T_PAIR) || (v2.type == T_QUAD))
|
if ((v2.type == T_PAIR) || (v2.type == T_QUAD))
|
||||||
@ -955,17 +955,35 @@ interpret(struct f_inst *what)
|
|||||||
else if (v2.type == T_IP)
|
else if (v2.type == T_IP)
|
||||||
i = ipa_to_u32(v2.val.px.ip);
|
i = ipa_to_u32(v2.val.px.ip);
|
||||||
#endif
|
#endif
|
||||||
else if ((v2.type == T_SET) && (op == 'd') && clist_set_type(v2.val.t, &dummy))
|
else if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy))
|
||||||
op = 'D';
|
arg_set = 1;
|
||||||
else
|
else
|
||||||
runtime("Can't add/delete non-pair");
|
runtime("Can't add/delete non-pair");
|
||||||
|
|
||||||
res.type = T_CLIST;
|
res.type = T_CLIST;
|
||||||
switch (op) {
|
switch (what->aux)
|
||||||
case 'a': res.val.ad = int_set_add(f_pool, v1.val.ad, i); break;
|
{
|
||||||
case 'd': res.val.ad = int_set_del(f_pool, v1.val.ad, i); break;
|
case 'a':
|
||||||
case 'D': res.val.ad = clist_del_matching(f_pool, v1.val.ad, v2.val.t); break;
|
if (arg_set)
|
||||||
default: bug("unknown Ca operation");
|
runtime("Can't add set");
|
||||||
|
res.val.ad = int_set_add(f_pool, v1.val.ad, i);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
if (!arg_set)
|
||||||
|
res.val.ad = int_set_del(f_pool, v1.val.ad, i);
|
||||||
|
else
|
||||||
|
res.val.ad = clist_filter(f_pool, v1.val.ad, v2.val.t, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
if (!arg_set)
|
||||||
|
runtime("Can't filter pair");
|
||||||
|
res.val.ad = clist_filter(f_pool, v1.val.ad, v2.val.t, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
bug("unknown Ca operation");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ clist l;
|
|||||||
l = add( l, (one,one) );
|
l = add( l, (one,one) );
|
||||||
l = delete( l, [(5,1),(6,one),(one,1)] );
|
l = delete( l, [(5,1),(6,one),(one,1)] );
|
||||||
l = delete( l, [(5,one),(6,one)] );
|
l = delete( l, [(5,one),(6,one)] );
|
||||||
l = delete( l, [(2,*)] );
|
l = filter( l, [(1,*)] );
|
||||||
print "Community list (1,2) ", l;
|
print "Community list (1,2) ", l;
|
||||||
print "Should be false: ", (2,3) ~ l, " ", l ~ [(2,*)], " ", l ~ [(one,3..6)];
|
print "Should be false: ", (2,3) ~ l, " ", l ~ [(2,*)], " ", l ~ [(one,3..6)];
|
||||||
print "Should be always true: ", l ~ [(*,*)];
|
print "Should be always true: ", l ~ [(*,*)];
|
||||||
|
Loading…
Reference in New Issue
Block a user