diff options
Diffstat (limited to 'filter')
-rw-r--r-- | filter/config.Y | 16 | ||||
-rw-r--r-- | filter/filter.c | 36 | ||||
-rw-r--r-- | filter/test.conf | 12 | ||||
-rw-r--r-- | filter/tree.c | 8 |
4 files changed, 53 insertions, 19 deletions
diff --git a/filter/config.Y b/filter/config.Y index 3e70a63e..3eb5b08f 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -618,16 +618,17 @@ bgp_path: ; bgp_path_tail1: - NUM bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN; $$->val = $1; } - | '*' bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASTERISK; $$->val = 0; } - | '?' bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_QUESTION; $$->val = 0; } - | bgp_path_expr bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN_EXPR; $$->val = (uintptr_t) $1; } - | { $$ = NULL; } + NUM bgp_path_tail1 { $$ = cfg_allocz(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN; $$->val = $1; } + | NUM DDOT NUM bgp_path_tail1 { $$ = cfg_allocz(sizeof(struct f_path_mask)); $$->next = $4; $$->kind = PM_ASN_RANGE; $$->val = $1; $$->val2 = $3; } + | '*' bgp_path_tail1 { $$ = cfg_allocz(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASTERISK; } + | '?' bgp_path_tail1 { $$ = cfg_allocz(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_QUESTION; } + | bgp_path_expr bgp_path_tail1 { $$ = cfg_allocz(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN_EXPR; $$->val = (uintptr_t) $1; } + | { $$ = NULL; } ; bgp_path_tail2: - NUM bgp_path_tail2 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN; $$->val = $1; } - | '?' bgp_path_tail2 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASTERISK; $$->val = 0; } + NUM bgp_path_tail2 { $$ = cfg_allocz(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN; $$->val = $1; } + | '?' bgp_path_tail2 { $$ = cfg_allocz(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASTERISK; } | { $$ = NULL; } ; @@ -725,6 +726,7 @@ term: | term '>' term { $$ = f_new_inst(); $$->code = '<'; $$->a1.p = $3; $$->a2.p = $1; } | term GEQ term { $$ = f_new_inst(); $$->code = P('<','='); $$->a1.p = $3; $$->a2.p = $1; } | term '~' term { $$ = f_new_inst(); $$->code = '~'; $$->a1.p = $1; $$->a2.p = $3; } + | term NMA term { $$ = f_new_inst(); $$->code = P('!','~'); $$->a1.p = $1; $$->a2.p = $3; } | '!' term { $$ = f_new_inst(); $$->code = '!'; $$->a1.p = $2; } | DEFINED '(' term ')' { $$ = f_new_inst(); $$->code = P('d','e'); $$->a1.p = $3; } diff --git a/filter/filter.c b/filter/filter.c index 7b3e550f..3282bd50 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -81,6 +81,10 @@ pm_format(struct f_path_mask *p, buffer *buf) buffer_puts(buf, "* "); break; + case PM_ASN_RANGE: + buffer_print(buf, "%u..%u ", p->val, p->val2); + break; + case PM_ASN_EXPR: buffer_print(buf, "%u ", f_eval_asn((struct f_inst *) p->val)); break; @@ -146,18 +150,29 @@ val_compare(struct f_val v1, struct f_val v2) } static int -pm_path_same(struct f_path_mask *m1, struct f_path_mask *m2) +pm_same(struct f_path_mask *m1, struct f_path_mask *m2) { while (m1 && m2) { - if ((m1->kind != m2->kind) || (m1->val != m2->val)) + if (m1->kind != m2->kind) return 0; + if (m1->kind == PM_ASN_EXPR) + { + if (!i_same((struct f_inst *) m1->val, (struct f_inst *) m2->val)) + return 0; + } + else + { + if ((m1->val != m2->val) || (m1->val2 != m2->val2)) + return 0; + } + m1 = m1->next; m2 = m2->next; } - return !m1 && !m2; + return !m1 && !m2; } /** @@ -182,7 +197,7 @@ val_same(struct f_val v1, struct f_val v2) switch (v1.type) { case T_PATH_MASK: - return pm_path_same(v1.val.path_mask, v2.val.path_mask); + return pm_same(v1.val.path_mask, v2.val.path_mask); case T_PATH: case T_CLIST: case T_ECLIST: @@ -673,6 +688,16 @@ interpret(struct f_inst *what) runtime( "~ applied on unknown type pair" ); res.val.i = !!res.val.i; break; + + case P('!','~'): + TWOARGS; + res.type = T_BOOL; + res.val.i = val_in_range(v1, v2); + if (res.val.i == CMP_ERROR) + runtime( "!~ applied on unknown type pair" ); + res.val.i = !res.val.i; + break; + case P('d','e'): ONEARG; res.type = T_BOOL; @@ -1415,7 +1440,8 @@ i_same(struct f_inst *f1, struct f_inst *f2) case P('A','p'): TWOARGS; break; case P('C','a'): TWOARGS; break; case P('a','f'): - case P('a','l'): ONEARG; break; + case P('a','l'): + case P('a','L'): ONEARG; break; #if 0 case P('R','C'): TWOARGS; diff --git a/filter/test.conf b/filter/test.conf index 5cafe551..a8c3a508 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -96,22 +96,28 @@ clist l2; eclist el; eclist el2; { + print "Entering path test..."; pm1 = / 4 3 2 1 /; - pm2 = [= 4 3 2 1 =]; + pm2 = [= 3..6 3 2 1..2 =]; print "Testing path masks: ", pm1, " ", pm2; p2 = prepend( + empty +, 1 ); p2 = prepend( p2, 2 ); p2 = prepend( p2, 3 ); p2 = prepend( p2, 4 ); - print "Testing paths: ", p2; + print "Testing path: (4 3 2 1) = ", p2; print "Should be true: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 3 ~ p2, " ", p2 ~ [2, 10..20], " ", p2 ~ [4, 10..20]; print "4 = ", p2.len; p2 = prepend( p2, 5 ); - print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2, " ", p2 ~ [8, ten..(2*ten)]; + print "Testing path: (5 4 3 2 1) = ", p2; + print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2, " ", p2 ~ [8, ten..(2*ten)], " ", p2 ~ [= 1..4 4 3 2 1 =], " ", p2 ~ [= 5 4 4..100 2 1 =]; print "Should be true: ", p2 ~ / ? 4 3 2 1 /, " ", p2, " ", / ? 4 3 2 1 /; print "Should be true: ", p2 ~ [= * 4 3 * 1 =], " ", p2, " ", [= * 4 3 * 1 =]; + print "Should be true: ", p2 ~ [= 5..6 4..10 1..3 1..3 1..65536 =]; print "Should be true: ", p2 ~ [= (3+2) (2*2) 3 2 1 =], " ", p2 ~ mkpath(5, 4); print "Should be true: ", p2.len = 5, " ", p2.first = 5, " ", p2.last = 1; + print "Should be true: ", pm1 = [= 4 3 2 1 =], " ", pm1 != [= 4 3 1 2 =], " ", + pm2 = [= 3..6 3 2 1..2 =], " ", pm2 != [= 3..6 3 2 1..3 =], " ", + [= 1 2 (1+2) =] = [= 1 2 (1+2) =], " ", [= 1 2 (1+2) =] != [= 1 2 (2+1) =]; print "5 = ", p2.len; print "Delete 3: ", delete(p2, 3); print "Filter 1-3: ", filter(p2, [1..3]); diff --git a/filter/tree.c b/filter/tree.c index ee9f448a..328c7184 100644 --- a/filter/tree.c +++ b/filter/tree.c @@ -82,7 +82,7 @@ build_tree(struct f_tree *from) if (len <= 1024) buf = alloca(len * sizeof(struct f_tree *)); else - buf = malloc(len * sizeof(struct f_tree *)); + buf = xmalloc(len * sizeof(struct f_tree *)); /* Convert a degenerated tree into an sorted array */ i = 0; @@ -94,7 +94,7 @@ build_tree(struct f_tree *from) root = build_tree_rec(buf, 0, len); if (len > 1024) - free(buf); + xfree(buf); return root; } @@ -163,9 +163,9 @@ tree_format(struct f_tree *t, buffer *buf) { buffer_puts(buf, "["); - tree_node_format(t, buf); + tree_node_format(t, buf); - /* Undo last separator */ + /* Undo last separator */ if (buf->pos[-1] != '[') buf->pos -= 2; |