]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Simplifies val_in_range().
authorOndrej Zajicek <santiago@crfreenet.org>
Wed, 2 Oct 2013 09:42:46 +0000 (11:42 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Wed, 2 Oct 2013 09:42:46 +0000 (11:42 +0200)
Also fixes missing type check for element ~ set.

filter/filter.c
lib/birdlib.h

index 0fc10f1f1281c15652856a7d282d39238df7e667..acdd8dc7beae75ae8d139a16e3280ff96dbf34fb 100644 (file)
@@ -220,39 +220,6 @@ fprefix_get_bounds(struct f_prefix *px, int *l, int *h)
     }
 }
 
-/*
- * val_simple_in_range - check if @v1 ~ @v2 for everything except sets
- */ 
-static int
-val_simple_in_range(struct f_val v1, struct f_val v2)
-{
-  if ((v1.type == T_PATH) && (v2.type == T_PATH_MASK))
-    return as_path_match(v1.val.ad, v2.val.path_mask);
-  if ((v1.type == T_INT) && (v2.type == T_PATH))
-    return as_path_is_member(v2.val.ad, v1.val.i);
-
-  if (((v1.type == T_PAIR) || (v1.type == T_QUAD)) && (v2.type == T_CLIST))
-    return int_set_contains(v2.val.ad, v1.val.i);
-#ifndef IPV6
-  /* IP->Quad implicit conversion */
-  if ((v1.type == T_IP) && (v2.type == T_CLIST))
-    return int_set_contains(v2.val.ad, ipa_to_u32(v1.val.px.ip));
-#endif
-  if ((v1.type == T_EC) && (v2.type == T_ECLIST))
-    return ec_set_contains(v2.val.ad, v1.val.ec);
-
-  if ((v1.type == T_STRING) && (v2.type == T_STRING))
-    return patmatch(v2.val.s, v1.val.s);
-
-  if ((v1.type == T_IP) && (v2.type == T_PREFIX))
-    return ipa_in_net(v1.val.px.ip, v2.val.px.ip, v2.val.px.len);
-
-  if ((v1.type == T_PREFIX) && (v2.type == T_PREFIX))
-    return net_in_net(v1.val.px.ip, v1.val.px.len, v2.val.px.ip, v2.val.px.len);
-
-  return CMP_ERROR;
-}
-
 static int
 clist_set_type(struct f_tree *set, struct f_val *v)
 {
@@ -396,47 +363,57 @@ eclist_filter(struct linpool *pool, struct adata *list, struct f_val set, int po
  * @v1: element
  * @v2: set
  *
- * Checks if @v1 is element (|~| operator) of @v2. Sets are internally represented as balanced trees, see
- * |tree.c| module (this is not limited to sets, but for non-set cases, val_simple_in_range() is called early).
+ * Checks if @v1 is element (|~| operator) of @v2.
  */
 static int
 val_in_range(struct f_val v1, struct f_val v2)
 {
-  int res;
+  if ((v1.type == T_PATH) && (v2.type == T_PATH_MASK))
+    return as_path_match(v1.val.ad, v2.val.path_mask);
 
-  res = val_simple_in_range(v1, v2);
+  if ((v1.type == T_INT) && (v2.type == T_PATH))
+    return as_path_is_member(v2.val.ad, v1.val.i);
+
+  if (((v1.type == T_PAIR) || (v1.type == T_QUAD)) && (v2.type == T_CLIST))
+    return int_set_contains(v2.val.ad, v1.val.i);
+#ifndef IPV6
+  /* IP->Quad implicit conversion */
+  if ((v1.type == T_IP) && (v2.type == T_CLIST))
+    return int_set_contains(v2.val.ad, ipa_to_u32(v1.val.px.ip));
+#endif
+
+  if ((v1.type == T_EC) && (v2.type == T_ECLIST))
+    return ec_set_contains(v2.val.ad, v1.val.ec);
+
+  if ((v1.type == T_STRING) && (v2.type == T_STRING))
+    return patmatch(v2.val.s, v1.val.s);
+
+  if ((v1.type == T_IP) && (v2.type == T_PREFIX))
+    return ipa_in_net(v1.val.px.ip, v2.val.px.ip, v2.val.px.len);
+
+  if ((v1.type == T_PREFIX) && (v2.type == T_PREFIX))
+    return net_in_net(v1.val.px.ip, v1.val.px.len, v2.val.px.ip, v2.val.px.len);
 
-  if (res != CMP_ERROR)
-    return res;
-  
   if ((v1.type == T_PREFIX) && (v2.type == T_PREFIX_SET))
     return trie_match_fprefix(v2.val.ti, &v1.val.px);
 
-  if ((v1.type == T_CLIST) && (v2.type == T_SET))
+  if (v2.type != T_SET)
+    return CMP_ERROR;
+
+  /* With integrated Quad<->IP implicit conversion */
+  if ((v1.type == v2.val.t->from.type) ||
+      ((IP_VERSION == 4) && (v1.type == T_QUAD) && (v2.val.t->from.type == T_IP)))
+    return !!find_tree(v2.val.t, v1);
+
+  if (v1.type == T_CLIST)
     return clist_match_set(v1.val.ad, v2.val.t);
 
-  if ((v1.type == T_ECLIST) && (v2.type == T_SET))
+  if (v1.type == T_ECLIST)
     return eclist_match_set(v1.val.ad, v2.val.t);
 
-  if ((v1.type == T_PATH) && (v2.type == T_SET))
+  if (v1.type == T_PATH)
     return as_path_match_set(v1.val.ad, v2.val.t);
 
-  if (v2.type == T_SET)
-    switch (v1.type) {
-    case T_ENUM:
-    case T_INT:
-    case T_PAIR:
-    case T_QUAD:
-    case T_IP:
-    case T_EC:
-      {
-       struct f_tree *n;
-       n = find_tree(v2.val.t, v1);
-       if (!n)
-         return 0;
-       return !! (val_simple_in_range(v1, n->from));   /* We turn CMP_ERROR into compared ok, and that's fine */
-      }
-    }
   return CMP_ERROR;
 }
 
index 479f3d5c1e38c6bff886c7220473681b4775d436..7e6e85267bf49f8caaad7404f1f48c3899677960 100644 (file)
 #define NULL ((void *) 0)
 #endif
 
+#ifndef IPV6
+#define IP_VERSION 4
+#else
+#define IP_VERSION 6
+#endif
+
 /* Macros for gcc attributes */
 
 #define NORET __attribute__((noreturn))