Simplifies val_in_range().
Also fixes missing type check for element ~ set.
This commit is contained in:
parent
ec57bbf67f
commit
b655596d1d
2 changed files with 42 additions and 59 deletions
|
@ -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
|
static int
|
||||||
clist_set_type(struct f_tree *set, struct f_val *v)
|
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
|
* @v1: element
|
||||||
* @v2: set
|
* @v2: set
|
||||||
*
|
*
|
||||||
* Checks if @v1 is element (|~| operator) of @v2. Sets are internally represented as balanced trees, see
|
* Checks if @v1 is element (|~| operator) of @v2.
|
||||||
* |tree.c| module (this is not limited to sets, but for non-set cases, val_simple_in_range() is called early).
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
val_in_range(struct f_val v1, struct f_val v2)
|
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))
|
if ((v1.type == T_PREFIX) && (v2.type == T_PREFIX_SET))
|
||||||
return trie_match_fprefix(v2.val.ti, &v1.val.px);
|
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);
|
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);
|
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);
|
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;
|
return CMP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,12 @@
|
||||||
#define NULL ((void *) 0)
|
#define NULL ((void *) 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef IPV6
|
||||||
|
#define IP_VERSION 4
|
||||||
|
#else
|
||||||
|
#define IP_VERSION 6
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Macros for gcc attributes */
|
/* Macros for gcc attributes */
|
||||||
|
|
||||||
#define NORET __attribute__((noreturn))
|
#define NORET __attribute__((noreturn))
|
||||||
|
|
Loading…
Reference in a new issue