[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