summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
Diffstat (limited to 'filter')
-rw-r--r--filter/config.Y1
-rw-r--r--filter/data.c11
-rw-r--r--filter/f-inst.c11
-rw-r--r--filter/test.conf11
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");