summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--filter/config.Y38
-rw-r--r--filter/data.h24
-rw-r--r--filter/f-inst.c38
3 files changed, 34 insertions, 66 deletions
diff --git a/filter/config.Y b/filter/config.Y
index 0e0df2fc..7b51cf72 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -376,29 +376,6 @@ f_new_lc_item(u32 f1, u32 t1, u32 f2, u32 t2, u32 f3, u32 t3)
return t;
}
-static inline struct f_inst *
-f_const_empty(enum f_type t)
-{
- switch (t) {
- case T_PATH:
- case T_CLIST:
- case T_ECLIST:
- case T_LCLIST:
- case T_EMPTY_LIST:
- return f_new_inst(FI_CONSTANT, (struct f_val) {
- .type = t,
- .val.ad = &null_adata,
- });
- case T_TLVLIST:
- return f_new_inst(FI_CONSTANT, (struct f_val) {
- .type = T_TLVLIST,
- .val.tl = NULL, // FIXME
- });
- default:
- return f_new_inst(FI_CONSTANT, (struct f_val) {});
- }
-}
-
/*
* Remove all new lines and doubled whitespaces
* and convert all tabulators to spaces
@@ -1062,13 +1039,14 @@ term:
| term_dot_method
- | EMPTY { $$ = f_const_empty(T_EMPTY_LIST); }
- | '+' EMPTY '+' { $$ = f_const_empty(T_PATH); }
- | '-' EMPTY '-' { $$ = f_const_empty(T_CLIST); }
- | '-' '-' EMPTY '-' '-' { $$ = f_const_empty(T_ECLIST); }
- | '-' '-' '-' EMPTY '-' '-' '-' { $$ = f_const_empty(T_LCLIST); }
- | '-' '-' '-' '-' EMPTY '-' '-' '-' '-' { $$ = f_const_empty(T_TLVLIST); }
- | PREPEND '(' term ',' term ')' { $$ = f_dispatch_method_x("prepend", $3->type, $3, $5); }
+ | EMPTY { $$ = f_new_inst(FI_CONSTANT, val_empty(T_EMPTY_LIST)); }
+ | '+' EMPTY '+' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_PATH)); }
+ | '-' EMPTY '-' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_CLIST)); }
+ | '-' '-' EMPTY '-' '-' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_ECLIST)); }
+ | '-' '-' '-' EMPTY '-' '-' '-' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_LCLIST)); }
+ | '-' '-' '-' '-' EMPTY '-' '-' '-' '-' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_TLVLIST)); }
+
+| PREPEND '(' term ',' term ')' { $$ = f_dispatch_method_x("prepend", $3->type, $3, $5); }
| ADD '(' term ',' term ')' { $$ = f_dispatch_method_x("add", $3->type, $3, $5); }
| DELETE '(' term ',' term ')' { $$ = f_dispatch_method_x("delete", $3->type, $3, $5); }
| FILTER '(' term ',' term ')' { $$ = f_dispatch_method_x("filter", $3->type, $3, $5); }
diff --git a/filter/data.h b/filter/data.h
index df53df40..874c269a 100644
--- a/filter/data.h
+++ b/filter/data.h
@@ -327,14 +327,36 @@ const struct te_tlvlist *tlvlist_filter(struct linpool *pool, const struct te_tl
/* Special undef value for paths and clists */
+
static inline int
-undef_value(struct f_val v)
+val_is_undefined(struct f_val v)
{
return ((v.type == T_PATH) || (v.type == T_CLIST) ||
(v.type == T_ECLIST) || (v.type == T_LCLIST)) &&
(v.val.ad == &null_adata);
}
+static inline struct f_val
+val_empty(enum f_type t)
+{
+ switch (t)
+ {
+ case T_PATH:
+ case T_CLIST:
+ case T_ECLIST:
+ case T_LCLIST:
+ case T_EMPTY_LIST:
+ return (struct f_val) { .type = t, .val.ad = &null_adata };
+
+ case T_TLVLIST:
+ return (struct f_val) { .type = T_TLVLIST, .val.tl = NULL }; // FIXME
+
+ default:
+ return (struct f_val) { };
+ }
+}
+
+
extern const struct f_val f_const_empty_prefix_set;
enum filter_return f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres);
diff --git a/filter/f-inst.c b/filter/f-inst.c
index e4a10221..e81bc2fb 100644
--- a/filter/f-inst.c
+++ b/filter/f-inst.c
@@ -493,7 +493,7 @@
INST(FI_DEFINED, 1, 1) {
ARG_ANY(1);
- RESULT(T_BOOL, i, (v1.type != T_VOID) && !undef_value(v1));
+ RESULT(T_BOOL, i, (v1.type != T_VOID) && !val_is_undefined(v1));
}
METHOD_R(T_NET, type, T_ENUM_NETTYPE, i, v1.val.net->type);
@@ -519,7 +519,7 @@
/* New variable is always the last on stack */
uint pos = curline.vbase + sym->offset;
- fstk->vstk[pos] = (struct f_val) { };
+ fstk->vstk[pos] = val_empty(sym->class & 0xff);
fstk->vcnt = pos + 1;
}
@@ -806,39 +806,7 @@
eattr *e = ea_find(*fs->eattrs, da.ea_code);
if (!e) {
- /* A special case: undefined as_path looks like empty as_path */
- if (da.type == EAF_TYPE_AS_PATH) {
- RESULT_(T_PATH, ad, &null_adata);
- break;
- }
-
- /* The same special case for int_set */
- if (da.type == EAF_TYPE_INT_SET) {
- RESULT_(T_CLIST, ad, &null_adata);
- break;
- }
-
- /* The same special case for ec_set */
- if (da.type == EAF_TYPE_EC_SET) {
- RESULT_(T_ECLIST, ad, &null_adata);
- break;
- }
-
- /* The same special case for lc_set */
- if (da.type == EAF_TYPE_LC_SET) {
- RESULT_(T_LCLIST, ad, &null_adata);
- break;
- }
-
- /* The same special case for tunnel encap */
- if (da.type == EAF_TYPE_TUNNEL_ENCAP) {
- RESULT_(T_TLVLIST, tl, NULL);
- runtime("Can't get null tunnel encap");
- break;
- }
-
- /* Undefined value */
- RESULT_VOID;
+ RESULT_VAL(val_empty(da.f_type));
break;
}