summaryrefslogtreecommitdiff
path: root/nest/a-path.c
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2019-08-06 16:58:13 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2019-08-06 16:58:13 +0200
commitef113c6f725349a2ab52f3cbef18403f82c84134 (patch)
treeda3ff7453dbb76cf5cf0290135483171842a0b38 /nest/a-path.c
parente2b530aa729f9c5973e498b45dd6f55ab669d1ac (diff)
Filter: Allow to use sets in path masks
Diffstat (limited to 'nest/a-path.c')
-rw-r--r--nest/a-path.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/nest/a-path.c b/nest/a-path.c
index a1b7c42f..4ee34cf4 100644
--- a/nest/a-path.c
+++ b/nest/a-path.c
@@ -740,6 +740,31 @@ pm_match(struct pm_pos *pos, u32 asn, u32 asn2)
return 0;
}
+static int
+pm_match_set(struct pm_pos *pos, struct f_tree *set)
+{
+ struct f_val asn = { .type = T_INT };
+
+ if (! pos->set)
+ {
+ asn.val.i = pos->val.asn;
+ return !!find_tree(set, &asn);
+ }
+
+ const u8 *p = pos->val.sp;
+ int len = *p++;
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ asn.val.i = get_as(p + i * BS);
+ if (find_tree(set, &asn))
+ return 1;
+ }
+
+ return 0;
+}
+
static void
pm_mark(struct pm_pos *pos, int i, int plen, int *nl, int *nh)
{
@@ -824,13 +849,17 @@ as_path_match(const struct adata *path, const struct f_path_mask *mask)
val2 = mask->item[m].to;
goto step;
case PM_QUESTION:
+ case PM_ASN_SET:
step:
nh = nl = -1;
for (i = h; i >= l; i--)
if (pos[i].mark)
{
pos[i].mark = 0;
- if ((mask->item[m].kind == PM_QUESTION) || pm_match(pos + i, val, val2))
+ if ((mask->item[m].kind == PM_QUESTION) ||
+ ((mask->item[m].kind != PM_ASN_SET) ?
+ pm_match(pos + i, val, val2) :
+ pm_match_set(pos + i, mask->item[m].set)))
pm_mark(pos, i, plen, &nl, &nh);
}