summaryrefslogtreecommitdiff
path: root/nest/a-set.c
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2012-03-15 20:42:29 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2012-03-15 21:07:58 +0100
commit0888a737b045b48106edbd28ba3cd62fcc8c191e (patch)
tree5a9321e48934ede411e7f8b1bc2c947c0f2a3b7e /nest/a-set.c
parent9f1500f50a0196f912eeb97e77ccf6873e186c29 (diff)
Extends set operations in filters.
Allows add/filter/delete clist on clist (set algebra on clists). Allows number ~ bgppath match.
Diffstat (limited to 'nest/a-set.c')
-rw-r--r--nest/a-set.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/nest/a-set.c b/nest/a-set.c
index 020d0978..42ef9b06 100644
--- a/nest/a-set.c
+++ b/nest/a-set.c
@@ -264,3 +264,67 @@ ec_set_del(struct linpool *pool, struct adata *list, u64 val)
return res;
}
+
+
+struct adata *
+int_set_union(struct linpool *pool, struct adata *l1, struct adata *l2)
+{
+ if (!l1)
+ return l2;
+ if (!l2)
+ return l1;
+
+ struct adata *res;
+ int len = int_set_get_size(l2);
+ u32 *l = int_set_get_data(l2);
+ u32 tmp[len];
+ u32 *k = tmp;
+ int i;
+
+ for (i = 0; i < len; i++)
+ if (!int_set_contains(l1, l[i]))
+ *k++ = l[i];
+
+ if (k == tmp)
+ return l1;
+
+ len = (k - tmp) * 4;
+ res = lp_alloc(pool, sizeof(struct adata) + l1->length + len);
+ res->length = l1->length + len;
+ memcpy(res->data, l1->data, l1->length);
+ memcpy(res->data + l1->length, tmp, len);
+ return res;
+}
+
+struct adata *
+ec_set_union(struct linpool *pool, struct adata *l1, struct adata *l2)
+{
+ if (!l1)
+ return l2;
+ if (!l2)
+ return l1;
+
+ struct adata *res;
+ int len = int_set_get_size(l2);
+ u32 *l = int_set_get_data(l2);
+ u32 tmp[len];
+ u32 *k = tmp;
+ int i;
+
+ for (i = 0; i < len; i += 2)
+ if (!ec_set_contains(l1, ec_get(l, i)))
+ {
+ *k++ = l[i];
+ *k++ = l[i+1];
+ }
+
+ if (k == tmp)
+ return l1;
+
+ len = (k - tmp) * 4;
+ res = lp_alloc(pool, sizeof(struct adata) + l1->length + len);
+ res->length = l1->length + len;
+ memcpy(res->data, l1->data, l1->length);
+ memcpy(res->data + l1->length, tmp, len);
+ return res;
+}