[PATCH 02/12] Check T_CLIST, T_ECLIST and T_PATH in val_compare()
Sergey Popovich
popovich_sergei at mail.ru
Mon Sep 30 20:24:18 CEST 2013
* Intdodoce list_compare() to compare clist and eclist as arrays of u32.
eclist stored as u64 with MSB first, so we could compare it also as u32.
* Introduce path_compare() to compare bgppath type. Compares path length,
and element by element, considering AS_PATH_SET more longer.
---
filter/filter.c | 76
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
nest/a-path.c | 7 -----
nest/attrs.h | 4 +++
3 files changed, 80 insertions(+), 7 deletions(-)
diff --git a/filter/filter.c b/filter/filter.c
index f92ee9a..6f59193 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -130,6 +130,77 @@ u64_cmp(u64 i1, u64 i2)
return (i1 > i2) - (i1 < i2);
}
+static int
+list_compare(struct adata *a1, struct adata *a2)
+{
+ u32 *l1, *l2;
+ int l, rc;
+
+ rc = (a1 > a2) - (a1 < a2);
+ if (!rc)
+ return rc;
+ if ((!!a1) != (!!a2))
+ return rc;
+
+ rc = uint_cmp(a1->length, a2->length);
+ if (rc)
+ return rc;
+
+ l1 = int_set_get_data(a1);
+ l2 = int_set_get_data(a2);
+ l = int_set_get_size(a1);
+
+ while (l--) {
+ rc = uint_cmp(*l1++, *l2++);
+ if (rc)
+ return rc;
+ }
+
+ return rc;
+}
+
+static int
+path_compare(struct adata *a1, struct adata *a2)
+{
+ u8 *p1, *q1;
+ u8 *p2, *q2;
+ int l, rc;
+
+ rc = (a1 > a2) - (a1 < a2);
+ if (!rc)
+ return rc;
+ if ((!!a1) != (!!a2))
+ return rc;
+
+ rc = int_cmp(as_path_getlen(a1), as_path_getlen(a2));
+ if (rc)
+ return rc;
+
+ p1 = a1->data;
+ q1 = p1 + a1->length;
+ p2 = a2->data;
+ q2 = p2 + a2->length;
+
+ while ((p1 < q1) && (p2 < q2)) {
+ rc = uint_cmp(*p1++, *p2++);
+ if (rc)
+ return -rc; /* AS_PATH_SET longer */
+
+ l = *p1++;
+ rc = int_cmp(l, *p2++);
+ if (rc)
+ return rc;
+
+ while (l--) {
+ rc = uint_cmp(get_as(p1++), get_as(p2++));
+ if (rc)
+ return rc;
+ }
+ }
+
+ return int_cmp((p1 < q1), (p2 < q2));
+}
+
/**
* val_compare - compare two values
* @v1: first value
@@ -180,6 +251,11 @@ val_compare(struct f_val v1, struct f_val v2)
return pm_path_compare(v1.val.path_mask, v2.val.path_mask);
case T_STRING:
return strcmp(v1.val.s, v2.val.s);
+ case T_CLIST:
+ case T_ECLIST:
+ return list_compare(v1.val.ad, v2.val.ad);
+ case T_PATH:
+ return path_compare(v1.val.ad, v2.val.ad);
case T_VOID:
return 0;
default:
diff --git a/nest/a-path.c b/nest/a-path.c
index b181298..1679886 100644
--- a/nest/a-path.c
+++ b/nest/a-path.c
@@ -15,13 +15,6 @@
#include "lib/string.h"
#include "filter/filter.h"
-// static inline void put_as(byte *data, u32 as) { put_u32(data, as); }
-// static inline u32 get_as(byte *data) { return get_u32(data); }
-
-#define put_as put_u32
-#define get_as get_u32
-#define BS 4
-
struct adata *
as_path_prepend(struct linpool *pool, struct adata *olda, u32 as)
{
diff --git a/nest/attrs.h b/nest/attrs.h
index 44a23e1..38639ae 100644
--- a/nest/attrs.h
+++ b/nest/attrs.h
@@ -25,6 +25,10 @@
* to 16bit slot (like in 16bit AS_PATH). See RFC 4893 for details
*/
+#define put_as put_u32
+#define get_as get_u32
+#define BS 4
+
struct f_tree;
struct adata *as_path_prepend(struct linpool *pool, struct adata
*olda, u32 as);
--
1.7.10.4
More information about the Bird-users
mailing list