summaryrefslogtreecommitdiff
path: root/filter
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2018-01-03 15:44:05 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2018-01-03 15:44:05 +0100
commit8f8671bcde738890d312ab91336f101465b3eeac (patch)
treebdadb7a99514b89e7b78d95dd09bf5597d1525b3 /filter
parent9bd8cb7c3ca23524cb7d69ee503e24658ad2ee42 (diff)
Filter: Handle undefined BGP paths as empty
The same is already done for clists. Also fixes defined() to work properly for paths and clists.
Diffstat (limited to 'filter')
-rw-r--r--filter/filter.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/filter/filter.c b/filter/filter.c
index aef4f44a..4e17f974 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -54,6 +54,17 @@
void (*bt_assert_hook)(int result, struct f_inst *assert);
+static struct adata undef_adata; /* adata of length 0 used for undefined */
+
+/* Special undef value for paths and clists */
+static inline int
+undef_value(struct f_val v)
+{
+ return ((v.type == T_PATH) || (v.type == T_CLIST) ||
+ (v.type == T_ECLIST) || (v.type == T_LCLIST)) &&
+ (v.val.ad == &undef_adata);
+}
+
static struct adata *
adata_empty(struct linpool *pool, int l)
{
@@ -815,7 +826,7 @@ interpret(struct f_inst *what)
case P('d','e'):
ONEARG;
res.type = T_BOOL;
- res.val.i = (v1.type != T_VOID);
+ res.val.i = (v1.type != T_VOID) && !undef_value(v1);
break;
case 'T':
ONEARG;
@@ -1001,24 +1012,31 @@ interpret(struct f_inst *what)
e = ea_find((*f_rte)->attrs->eattrs, code);
if (!e) {
- /* A special case: undefined int_set looks like empty int_set */
+ /* A special case: undefined as_path looks like empty as_path */
+ if ((what->aux & EAF_TYPE_MASK) == EAF_TYPE_AS_PATH) {
+ res.type = T_PATH;
+ res.val.ad = &undef_adata;
+ break;
+ }
+
+ /* The same special case for int_set */
if ((what->aux & EAF_TYPE_MASK) == EAF_TYPE_INT_SET) {
res.type = T_CLIST;
- res.val.ad = adata_empty(f_pool, 0);
+ res.val.ad = &undef_adata;
break;
}
/* The same special case for ec_set */
if ((what->aux & EAF_TYPE_MASK) == EAF_TYPE_EC_SET) {
res.type = T_ECLIST;
- res.val.ad = adata_empty(f_pool, 0);
+ res.val.ad = &undef_adata;
break;
}
/* The same special case for lc_set */
if ((what->aux & EAF_TYPE_MASK) == EAF_TYPE_LC_SET) {
res.type = T_LCLIST;
- res.val.ad = adata_empty(f_pool, 0);
+ res.val.ad = &undef_adata;
break;
}