summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2013-10-02 11:42:46 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2013-10-02 11:42:46 +0200
commitb655596d1d9ad7664d12249c946ba3483b2de3f0 (patch)
tree6944cbd86ff58e7b023c3ecd153efca11a0203e9 /filter
parentec57bbf67f9e4221fb98f6769f592cedf2eb2d24 (diff)
Simplifies val_in_range().
Also fixes missing type check for element ~ set.
Diffstat (limited to 'filter')
-rw-r--r--filter/filter.c95
1 files changed, 36 insertions, 59 deletions
diff --git a/filter/filter.c b/filter/filter.c
index 0fc10f1f..acdd8dc7 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -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;
}