From b655596d1d9ad7664d12249c946ba3483b2de3f0 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Wed, 2 Oct 2013 11:42:46 +0200 Subject: [PATCH] Simplifies val_in_range(). Also fixes missing type check for element ~ set. --- filter/filter.c | 95 +++++++++++++++++++------------------------------ lib/birdlib.h | 6 ++++ 2 files changed, 42 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; } diff --git a/lib/birdlib.h b/lib/birdlib.h index 479f3d5c..7e6e8526 100644 --- a/lib/birdlib.h +++ b/lib/birdlib.h @@ -34,6 +34,12 @@ #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))