From a0fe1944d12771d60986a352552e5f4b306e5f7f Mon Sep 17 00:00:00 2001 From: Ondrej Filip Date: Wed, 8 Jun 2016 16:22:44 +0200 Subject: Add AS# ranges to bgpmask. --- filter/config.Y | 1 + filter/filter.c | 4 ++++ filter/test.conf | 9 ++++++--- 3 files changed, 11 insertions(+), 3 deletions(-) (limited to 'filter') diff --git a/filter/config.Y b/filter/config.Y index b94f5dff..e53d8def 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -627,6 +627,7 @@ bgp_path: bgp_path_tail1: NUM bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN; $$->val = $1; } + | NUM DDOT NUM bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $4; $$->kind = PM_ASN_RANGE; $$->val = $1; $$->val2 = $3; } | '*' 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; } diff --git a/filter/filter.c b/filter/filter.c index eddf4228..dce98e4d 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -79,6 +79,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; diff --git a/filter/test.conf b/filter/test.conf index a99d0a51..ad8f9386 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -90,20 +90,23 @@ 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 "5 = ", p2.len; -- cgit v1.2.3 From 122deb6d5b14f46f3cfb25bf3f5726005d6a3b3e Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Thu, 9 Jun 2016 00:30:41 +0200 Subject: Filters: Fixes pm_same() w.r.t. ASN ranges and ASN expressions This is necessary for proper detection of filter changes during reconfigurations. --- filter/config.Y | 16 ++++++++-------- filter/filter.c | 17 ++++++++++++++--- filter/test.conf | 3 +++ 3 files changed, 25 insertions(+), 11 deletions(-) (limited to 'filter') diff --git a/filter/config.Y b/filter/config.Y index e53d8def..da605710 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -626,17 +626,17 @@ bgp_path: ; bgp_path_tail1: - NUM bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN; $$->val = $1; } - | NUM DDOT NUM bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $4; $$->kind = PM_ASN_RANGE; $$->val = $1; $$->val2 = $3; } - | '*' 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; } ; diff --git a/filter/filter.c b/filter/filter.c index dce98e4d..c61377b7 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -163,13 +163,24 @@ 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; } @@ -199,7 +210,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: diff --git a/filter/test.conf b/filter/test.conf index ad8f9386..f61f0658 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -109,6 +109,9 @@ eclist el2; 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]); -- cgit v1.2.3 From f1f39bb9d8e2260fe181240dd8194b06bdcfb54f Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Fri, 1 Jul 2016 11:03:13 +0200 Subject: Filter: Fixes reconfiguration with last_nonaggregated operator --- filter/filter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'filter') diff --git a/filter/filter.c b/filter/filter.c index c61377b7..30571e5a 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -1461,7 +1461,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; case P('R','C'): TWOARGS; /* Does not really make sense - ROA check resuls may change anyway */ -- cgit v1.2.3 From 33d22f0e9e79c387c492d1cf16bdb723ca1d588a Mon Sep 17 00:00:00 2001 From: Ondřej Surý Date: Tue, 16 Aug 2016 09:24:12 +0200 Subject: whitespace fixes --- filter/filter.c | 2 +- filter/tree.c | 4 ++-- sysdep/unix/io.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'filter') diff --git a/filter/filter.c b/filter/filter.c index 30571e5a..ccdfed36 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -185,7 +185,7 @@ pm_same(struct f_path_mask *m1, struct f_path_mask *m2) m2 = m2->next; } - return !m1 && !m2; + return !m1 && !m2; } /** diff --git a/filter/tree.c b/filter/tree.c index ee9f448a..59ebf579 100644 --- a/filter/tree.c +++ b/filter/tree.c @@ -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; diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index 8198743d..120eb906 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -2235,7 +2235,7 @@ io_loop(void) if (pfd[s->index].revents & (POLLHUP | POLLERR)) { sk_err(s, pfd[s->index].revents); - goto next2; + goto next2; } current_sock = sk_next(s); -- cgit v1.2.3 From bc00f058154bb4a630d24d64a55b5f181d235c63 Mon Sep 17 00:00:00 2001 From: Pavel Tvrdik Date: Tue, 6 Sep 2016 17:18:15 +0200 Subject: Filter: Prefer xmalloc/xfree to malloc/free --- filter/tree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'filter') diff --git a/filter/tree.c b/filter/tree.c index 59ebf579..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; } -- cgit v1.2.3 From 768d5e1058693d2bfb7c3bcbe04306097c3246a0 Mon Sep 17 00:00:00 2001 From: Pavel Tvrdik Date: Tue, 20 Sep 2016 15:13:01 +0200 Subject: Add !~ operator to filter grammar --- conf/cf-lex.l | 1 + conf/confbase.Y | 2 +- doc/bird.sgml | 38 +++++++++++++++++++------------------- filter/config.Y | 1 + filter/filter.c | 10 ++++++++++ 5 files changed, 32 insertions(+), 20 deletions(-) (limited to 'filter') diff --git a/conf/cf-lex.l b/conf/cf-lex.l index 61ea4527..d2aa6402 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -246,6 +246,7 @@ else: { . \!\= return NEQ; +\!\~ return NMA; \<\= return LEQ; \>\= return GEQ; \&\& return AND; diff --git a/conf/confbase.Y b/conf/confbase.Y index 5f487c1d..c14c23c7 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -82,7 +82,7 @@ CF_DECLS %nonassoc PREFIX_DUMMY %left AND OR -%nonassoc '=' '<' '>' '~' GEQ LEQ NEQ PO PC +%nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA PO PC %left '+' '-' %left '*' '/' '%' %left '!' diff --git a/doc/bird.sgml b/doc/bird.sgml index af5b7980..07a2d470 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1016,9 +1016,9 @@ foot). of type @@ -1213,19 +1213,19 @@ foot).

The filter language supports common integer operators (+,-,*,/), parentheses There is one operator related to ROA infrastructure - ' 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 ccdfed36..2f5f00d8 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -716,6 +716,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; -- cgit v1.2.3