summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
Diffstat (limited to 'filter')
-rw-r--r--filter/config.Y22
-rw-r--r--filter/filter.c14
-rw-r--r--filter/filter.h14
-rw-r--r--filter/test.conf2
4 files changed, 35 insertions, 17 deletions
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 /;