[PATCH 06/12] Reintroduce RESET predicate in filters to allow emptying objects.
Sergey Popovich
popovich_sergei at mail.ru
Mon Sep 30 20:30:46 CEST 2013
Use RESET as predicate to set to empty value of dynamic attribute
value in filters. Leave EMPTY for backwad compatibility, altought
it not documented enywhere.
Uninline f_generate_empty() and refactor code in error path.
Remove MATCH and CONTAINS from keyword list.
---
doc/bird.sgml | 4 ++++
filter/config.Y | 35 ++++++++++++++++-------------------
2 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/doc/bird.sgml b/doc/bird.sgml
index 050acf3..d1d7860 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -1053,6 +1053,8 @@ incompatible with each other (that is to prevent
you from shooting in the foot).
I.e., <cf/filter/ do the same as <cf/delete/ with inverted
set <m/A/.
+ <cf><m/P/.reset</cf> deletes all ASNs from path <m/P/.
+
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/.
@@ -1098,6 +1100,8 @@ incompatible with each other (that is to prevent
you from shooting in the foot).
set <m/P/. <m/P/ may also be a clist, which works analogously;
i.e., it works as clist intersection.
+ <cf><m/C/.reset</cf> deletes all items from clist <m/C/.
+
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
diff --git a/filter/config.Y b/filter/config.Y
index 04acfba..faa02f5 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -115,32 +115,36 @@ f_new_ec_item(u32 kind, u32 ipv4_used, u32 key,
u32 vf, u32 vt)
return t;
}
-static inline struct f_inst *
+static struct f_inst *
f_generate_empty(struct f_inst *dyn)
-{ - struct f_inst *e = f_new_inst();
- e->code = 'E';
+{
+ struct f_inst *e;
+ u16 aux;
switch (dyn->aux & EAF_TYPE_MASK) {
case EAF_TYPE_AS_PATH:
- e->aux = T_PATH;
+ aux = T_PATH;
break;
case EAF_TYPE_INT_SET:
- e->aux = T_CLIST;
+ aux = T_CLIST;
break;
case EAF_TYPE_EC_SET:
- e->aux = T_ECLIST;
+ aux = T_ECLIST;
break;
default:
cf_error("Can't empty that attribute");
}
+ e = f_new_inst();
+ e->code = 'E';
+ e->aux = aux;
+
dyn->code = P('e','S');
dyn->a1.p = e;
+
return dyn;
}
-
static inline struct f_inst *
f_generate_dpair(struct f_inst *t1, struct f_inst *t2)
{
@@ -265,10 +269,9 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
PREFERENCE,
LEN,
DEFINED,
- ADD, DELETE, CONTAINS, RESET,
- PREPEND, FIRST, LAST, MATCH,
+ ADD, DELETE, RESET, EMPTY,
+ PREPEND, FIRST, LAST,
ROA_CHECK,
- EMPTY,
FILTER, WHERE, EVAL)
%nonassoc THEN
@@ -727,14 +730,6 @@ term:
| term '.' FIRST { $$ = f_new_inst(); $$->code = P('a','f'); $$->a1.p
= $1; }
| term '.' LAST { $$ = f_new_inst(); $$->code = P('a','l'); $$->a1.p
= $1; }
-/* Communities */
-/* This causes one shift/reduce conflict
- | rtadot dynamic_attr '.' ADD '(' term ')' { }
- | rtadot dynamic_attr '.' DELETE '(' term ')' { }
- | rtadot dynamic_attr '.' CONTAINS '(' term ')' { }
- | rtadot dynamic_attr '.' RESET{ }
-*/
-
| '+' EMPTY '+' { $$ = f_new_inst(); $$->code = 'E'; $$->aux = T_PATH; }
| '-' EMPTY '-' { $$ = f_new_inst(); $$->code = 'E'; $$->aux = T_CLIST; }
| '-' '-' EMPTY '-' '-' { $$ = f_new_inst(); $$->code = 'E'; $$->aux =
T_ECLIST; }
@@ -880,6 +875,8 @@ cmd:
| rtadot dynamic_attr '.' EMPTY ';' { $$ = f_generate_empty($2); }
+ | rtadot dynamic_attr '.' RESET ';' { $$ = f_generate_empty($2); }
+
| 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 '.' DELETE '(' term ')' ';' { $$ =
f_generate_complex( P('C','a'), 'd', $2, $6 ); }
--
1.7.10.4
More information about the Bird-users
mailing list