]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
filter_same() implemented. Don't bet on it, yet.
authorPavel Machek <pavel@ucw.cz>
Mon, 31 Jan 2000 17:44:22 +0000 (17:44 +0000)
committerPavel Machek <pavel@ucw.cz>
Mon, 31 Jan 2000 17:44:22 +0000 (17:44 +0000)
filter/filter.c
filter/filter.h
filter/test.conf
filter/tree.c

index 558ee61e9080c06eff91639d25d9430f964488df..103710ea60ab825dbd7d1b2c35544df451c3cf34 100644 (file)
 
 struct f_inst *startup_func = NULL;
 
-#define runtime(x) do { \
-    log( L_ERR x ); \
-    res.type = T_RETURN; \
-    res.val.i = F_ERROR; \
-    return res; \
-  } while(0)
-
-#define ARG(x,y) \
-       x = interpret(what->y); \
-       if (x.type == T_RETURN) \
-               return x;
-
-#define ONEARG ARG(v1, a1.p)
-#define TWOARGS ARG(v1, a1.p) \
-               ARG(v2, a2.p)
-#define TWOARGS_C TWOARGS \
-                  if (v1.type != v2.type) \
-                   runtime( "Can not operate with values of incompatible types" );
-
 #define CMP_ERROR 999
 
 /* Compare two values, returns -1, 0, 1 compared, ERROR 999 */
@@ -160,7 +141,24 @@ val_print(struct f_val v)
 static struct rte **f_rte, *f_rte_old;
 static struct linpool *f_pool;
 
-static struct f_val interpret(struct f_inst *what);
+#define runtime(x) do { \
+    log( L_ERR x ); \
+    res.type = T_RETURN; \
+    res.val.i = F_ERROR; \
+    return res; \
+  } while(0)
+
+#define ARG(x,y) \
+       x = interpret(what->y); \
+       if (x.type == T_RETURN) \
+               return x;
+
+#define ONEARG ARG(v1, a1.p)
+#define TWOARGS ARG(v1, a1.p) \
+               ARG(v2, a2.p)
+#define TWOARGS_C TWOARGS \
+                  if (v1.type != v2.type) \
+                   runtime( "Can not operate with values of incompatible types" );
 
 static struct f_val
 interpret(struct f_inst *what)
@@ -412,6 +410,77 @@ interpret(struct f_inst *what)
   return res;
 }
 
+#define ARG(x,y) \
+       if (!i_same(f1->y, f2->y)) \
+               return 0;
+
+#define ONEARG ARG(v1, a1.p)
+#define TWOARGS ARG(v1, a1.p) \
+               ARG(v2, a2.p)
+
+#define A2_SAME if (f1->a2.i != f2->a2.i) return 0;
+
+int
+i_same(struct f_inst *f1, struct f_inst *f2)
+{
+  if (!f1)
+    return 1;
+  if ((!!f1) != (!!f2))
+    return 0;
+  if (f1->aux != f2->aux)
+    return 0;
+  if (f1->code != f2->code)
+    return 0;
+
+  switch(f1->code) {
+  case ',': /* fall through */
+  case '+':
+  case '/':
+  case '!=':
+  case '==':
+  case '<':
+  case '<=': TWOARGS; break;
+
+  case '~': TWOARGS; break;
+  case 'de': ONEARG; break;
+
+  case 's':
+    ARG(v2, a2.p);
+    {
+      struct symbol *s1, *s2;
+      s1 = f1->a1.p;
+      s2 = f2->a1.p;
+      if (strcmp(s1->name, s2->name))
+       return 0;
+      if (s1->class != s2->class)
+       return 0;
+    }
+    break;
+
+  case 'c': A2_SAME; break;
+  case 'C': 
+    if (val_compare(* (struct f_val *) f1->a1.p, * (struct f_val *) f2->a2.p))
+      return 0;
+    break;
+  case 'p': ONEARG; break;
+  case '?': TWOARGS; break;
+  case '0': break;
+  case 'p,': ONEARG; A2_SAME; break;
+  case 'a': A2_SAME; break;
+  case 'ea': A2_SAME; break;
+  case 'eS': ONEARG; A2_SAME; break;
+
+  case 'cp': ONEARG; break;
+  case 'ca': /* CALL, FIXME: exponential in some cases */
+             ONEARG; if (!i_same(f1->a2.p, f2->a2.p)) return 0; break;
+  case 'SW': ONEARG; if (!same_tree(f1->a2.p, f2->a2.p)) return 0; break;
+  case 'iM': TWOARGS; break;
+  default:
+    bug( "Unknown instruction %d in same (%c)", f1->code, f1->code & 0xff);
+  }
+  return i_same(f1->next, f2->next);
+}
+
 /* FIXME: tmp_attrs is unreferenced. That can't be right */
 int
 f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool)
@@ -432,6 +501,7 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc
 }
 
 
+
 void
 filters_postconfig(void)
 {
@@ -448,6 +518,5 @@ filters_postconfig(void)
 int
 filter_same(struct filter *new, struct filter *old)
 {
-  /* FIXME: This has to be defined! */
-  return new == old;
+  return i_same(new->root, old->root);
 }
index 2fe665398e77b03004f52ccb70fe9d2962a79951..ace72e47921ac957081ef8666b6df70ef0d021c8 100644 (file)
@@ -61,6 +61,7 @@ struct f_tree *f_new_tree(void);
 
 struct f_tree *build_tree(struct f_tree *);
 struct f_tree *find_tree(struct f_tree *t, struct f_val val);
+int same_tree(struct f_tree *t1, struct f_tree *t2);
 
 struct ea_list;
 struct rte;
@@ -69,6 +70,8 @@ int f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, s
 char *filter_name(struct filter *filter);
 int filter_same(struct filter *new, struct filter *old);
 
+int i_same(struct f_inst *f1, struct f_inst *f2);
+
 int val_compare(struct f_val v1, struct f_val v2);
 void val_print(struct f_val v);
 
index e2da6d79271b76dce68f597f017ead42a1aa35d1..616dbc58e84331917b9e2e0ee549184f91665209 100644 (file)
@@ -42,7 +42,7 @@ ip p;
        print "  data types: must be false: " 1 ~ [ 2, 3, 4 ] "," 5 ~ [ 2, 3, 4, 7..11 ] "," 1.2.3.4 ~ [ 1.2.3.3, 1.2.3.5 ] "," (1,2) > (2,2) "," (1,1) > (1,1) "," 1.0.0.0/8 ~ [ 1.0.0.0/8- ] "," 1.2.0.0/17 ~ [ 1.0.0.0/8{ 15 , 16 } ];
 
        px = 1.2.0.0/18;
-       print "Testing prefixes: 1.0.0.0/18 = " px;
+       print "Testing prefixes: 1.2.0.0/18 = " px;
        p = 127.1.2.3;
        print "Testing mask : 127.0.0.0 = " p.mask(8);
        print "Testing pairs: (1,2) = " (1,2);
index 43888f0be3c96925dd0a6a14b036df749751b71d..5e57bb73f3fdd36f1a625666a6ccb3ce2a58e445 100644 (file)
@@ -123,3 +123,23 @@ f_new_tree(void)
   ret->data = NULL;
   return ret;
 }
+
+int
+same_tree(struct f_tree *t1, struct f_tree *t2)
+{
+  if ((!!t1) != (!!t2))
+    return 0;
+  if (!t1)
+    return 1;
+  if (val_compare(t1->from, t2->from))
+    return 0;
+  if (val_compare(t1->to, t2->to))
+    return 0;
+  if (!same_tree(t1->left, t2->left))
+    return 0;
+  if (!same_tree(t1->right, t2->right))
+    return 0;
+  if (!i_same(t1->data, t2->data))
+    return 0;
+  return 1;
+}