diff options
Diffstat (limited to 'filter')
-rw-r--r-- | filter/config.Y | 1 | ||||
-rw-r--r-- | filter/data.c | 11 | ||||
-rw-r--r-- | filter/f-inst.c | 11 | ||||
-rw-r--r-- | filter/test.conf | 11 |
4 files changed, 32 insertions, 2 deletions
diff --git a/filter/config.Y b/filter/config.Y index 77424a8b..557a951f 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -662,6 +662,7 @@ bgp_path_tail: } | '*' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_ASTERISK }, }); $$->next = $2; } | '?' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_QUESTION }, }); $$->next = $2; } + | '+' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .kind = PM_LOOP }, }); $$->next = $2; } | bgp_path_expr bgp_path_tail { $$ = $1; $$->next = $2; } | { $$ = NULL; } ; diff --git a/filter/data.c b/filter/data.c index 62edd9e0..40220255 100644 --- a/filter/data.c +++ b/filter/data.c @@ -93,6 +93,8 @@ adata_empty(struct linpool *pool, int l) static void pm_format(const struct f_path_mask *p, buffer *buf) { + int loop = 0; + buffer_puts(buf, "[= "); for (uint i=0; i<p->len; i++) @@ -111,6 +113,10 @@ pm_format(const struct f_path_mask *p, buffer *buf) buffer_puts(buf, "* "); break; + case PM_LOOP: + loop = 1; + break; + case PM_ASN_RANGE: buffer_print(buf, "%u..%u ", p->item[i].from, p->item[i].to); break; @@ -119,6 +125,11 @@ pm_format(const struct f_path_mask *p, buffer *buf) ASSERT(0); } + if (loop && (p->item[i].kind != PM_LOOP)) + { + buffer_puts(buf, "+ "); + loop = 0; + } } buffer_puts(buf, "=]"); diff --git a/filter/f-inst.c b/filter/f-inst.c index 63a6bdab..df908e26 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -311,6 +311,17 @@ for (uint i=0; i<whati->varcount; i++) { switch (vv(i).type) { case T_PATH_MASK_ITEM: + if (vv(i).val.pmi.kind == PM_LOOP) + { + if (i == 0) + runtime("Path mask iterator '+' cannot be first"); + + /* We want PM_LOOP as prefix operator */ + pm->item[i] = pm->item[i - 1]; + pm->item[i - 1] = vv(i).val.pmi; + break; + } + pm->item[i] = vv(i).val.pmi; break; diff --git a/filter/test.conf b/filter/test.conf index 634816fd..63af25bb 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -646,7 +646,6 @@ int set set12; bt_assert(delete(p2, 3) = prepend(prepend(prepend(prepend(+empty+, 1), 2), 4), 5)); bt_assert(filter(p2, [1..3]) = prepend(prepend(prepend(+empty+, 1), 2), 3)); - pm1 = [= 1 2 * 3 4 5 =]; p2 = prepend( + empty +, 5 ); p2 = prepend( p2, 4 ); p2 = prepend( p2, 3 ); @@ -654,9 +653,17 @@ int set set12; p2 = prepend( p2, 2 ); p2 = prepend( p2, 1 ); - bt_assert(p2 ~ pm1); + bt_assert(p2 !~ [= 1 2 3 4 5 =]); + bt_assert(p2 ~ [= 1 2 * 4 5 =]); + bt_assert(p2 ~ [= 1 2 * 3 4 5 =]); + bt_assert(p2 ~ [= 1 2 3+ 4 5 =]); + bt_assert(p2 ~ [= 1 2 3+ 4+ 5 =]); + bt_assert(p2 !~ [= 1 2 3+ 5+ 4 5 =]); + bt_assert(p2 !~ [= 1 2 3 3 5+ 4 5 =]); bt_assert(delete(p2, 3) = prepend(prepend(prepend(prepend(+empty+, 5), 4), 2), 1)); bt_assert(delete(p2, [4..5]) = prepend(prepend(prepend(prepend(+empty+, 3), 3), 2), 1)); + + bt_assert(format([= 1 2+ 3 =]) = "[= 1 2 + 3 =]"); } bt_test_suite(t_path, "Testing paths"); |