diff --git a/filter/config.Y b/filter/config.Y index 953dfbcd..04c0af55 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -65,7 +65,7 @@ CF_DECLS CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, ACCEPT, REJECT, ERROR, QUITBIRD, - INT, BOOL, IP, PREFIX, PAIR, SET, STRING, BGP_PATH, + INT, BOOL, IP, PREFIX, PAIR, SET, STRING, BGPMASK, BGPPATH, CLIST, IF, THEN, ELSE, CASE, TRUE, FALSE, FROM, GW, NET, MASK, SOURCE, @@ -106,7 +106,9 @@ type: | PREFIX { $$ = T_PREFIX; } | PAIR { $$ = T_PAIR; } | STRING { $$ = T_STRING; } - | BGP_PATH { $$ = T_PATH_MASK; } + | BGPMASK { $$ = T_PATH_MASK; } + | BGPPATH { $$ = T_PATH; } + | CLIST { $$ = T_CLIST; } | type SET { switch ($1) { default: @@ -406,16 +408,16 @@ term: | term '.' MASK '(' term ')' { $$ = f_new_inst(); $$->code = P('i','M'); $$->a1.p = $1; $$->a2.p = $5; } /* Communities */ - - | term '.' ADD '(' term ')' { } - | term '.' DELETE '(' term ')' { } - | term '.' CONTAINS '(' term ')' { } - | term '.' RESET { } +/* 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 { } +*/ /* Paths */ - | rtadot PATH '~' term { } - | rtadot PATH '.' APPEND '(' term ')' { } - | rtadot PATH '.' LEN { $$->code = P('P','l'); } + | rtadot dynamic_attr '.' APPEND '(' term ')' { } + | rtadot dynamic_attr '.' LEN { $$->code = P('P','l'); } /* function_call is inlined here */ | SYM '(' var_list ')' { diff --git a/filter/filter.c b/filter/filter.c index 2da2a28e..a2d827a6 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -60,6 +60,9 @@ val_compare(struct f_val v1, struct f_val v2) int val_simple_in_range(struct f_val v1, struct f_val v2) { + if ((v1.type == T_PATH) && (v2.type == T_PATH_MASK)) + return path_match(&v1.val.ad->data, v1.val.ad->length, v2.val.path_mask); + if ((v1.type == T_IP) && (v2.type == T_PREFIX)) return !(ipa_compare(ipa_and(v2.val.px.ip, ipa_mkmask(v2.val.px.len)), ipa_and(v1.val.px.ip, ipa_mkmask(v2.val.px.len)))); @@ -133,6 +136,7 @@ val_print(struct f_val v) case T_PAIR: PRINTF( "(%d,%d)", v.val.i >> 16, v.val.i & 0xffff ); break; case T_SET: tree_print( v.val.t ); PRINTF( "\n" ); break; case T_ENUM: PRINTF( "(enum %x)%d", v.type, v.val.i ); break; + case T_PATH: PRINTF( "%s", path_format(&v.val.ad->data, v.val.ad->length)); break; case T_PATH_MASK: debug( "(path " ); { struct f_path_mask *p = v.val.s; while (p) { debug("%d ", p->val); p=p->next; } debug(")" ); } break; default: PRINTF( "[unknown type %x]", v.type ); #undef PRINTF @@ -341,11 +345,14 @@ interpret(struct f_inst *what) res.type = T_VOID; break; } - res.type = what->aux; + res.type = what->aux; /* FIXME: should check type? */ switch (what->a1.i) { case T_INT: res.val.i = e->u.data; break; + case T_PATH: + res.val.ad = e->u.ptr; + break; } } break; @@ -369,6 +376,11 @@ interpret(struct f_inst *what) runtime( "Setting int attribute to non-int value" ); l->attrs[0].u.data = v1.val.i; break; + case EAF_TYPE_AS_PATH: + if (v1.type != T_PATH) + runtime( "Setting path attribute to non-path value" ); + l->attrs[0].u.ptr = v1.val.ad; + break; case EAF_TYPE_UNDEF: if (v1.type != T_VOID) runtime( "Setting void attribute to non-void value" ); diff --git a/filter/filter.h b/filter/filter.h index ab337398..45f9cd6c 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -39,6 +39,11 @@ struct prefix { /* If range then prefix must be in range (len >> 16 & 0xff, len >> 8 & 0xff) */ }; +struct f_path_mask { + struct f_path_mask *next; + int val; +}; + struct f_val { int type; union { @@ -47,14 +52,11 @@ struct f_val { struct prefix px; char *s; struct f_tree *t; + struct adata *ad; + struct f_path_mask *path_mask; } val; }; -struct f_path_mask { - struct f_path_mask *next; - int val; -}; - struct filter { char *name; struct f_inst *root; @@ -116,6 +118,8 @@ void val_print(struct f_val v); #define T_PREFIX 0x21 #define T_STRING 0x22 #define T_PATH_MASK 0x23 /* mask for BGP path */ +#define T_PATH 0x24 /* BGP path */ +#define T_CLIST 0x25 /* Community list */ #define T_RETURN 0x40 #define T_SET 0x80 diff --git a/filter/test.conf b/filter/test.conf index cc62cd17..94ed5566 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -30,7 +30,7 @@ function fifteen() } function paths() -bgp_path p; +bgpmask p; { print "Testing paths"; p = / 1 2 3 4 /;