diff options
Diffstat (limited to 'filter/filter.c')
-rw-r--r-- | filter/filter.c | 73 |
1 files changed, 33 insertions, 40 deletions
diff --git a/filter/filter.c b/filter/filter.c index ec155ee..de7a97b 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -473,27 +473,10 @@ interpret(struct f_inst *what) case 's': ARG(v2, a2.p); sym = what->a1.p; - switch (res.type = v2.type) { - case T_VOID: runtime( "Can't assign void values" ); - case T_ENUM: - case T_BOOL: - case T_INT: - case T_PAIR: - case T_STRING: - case T_IP: - case T_PREFIX: - case T_PREFIX_SET: - case T_SET: - case T_PATH: - case T_PATH_MASK: - case T_CLIST: - if (sym->class != (SYM_VARIABLE | v2.type)) - runtime( "Assigning to variable of incompatible type" ); - * (struct f_val *) sym->def = v2; - break; - default: - bug( "Set to invalid type" ); - } + if ((sym->class != (SYM_VARIABLE | v2.type)) && + (v2.type != T_VOID)) + runtime( "Assigning to variable of incompatible type" ); + * (struct f_val *) sym->def = v2; break; /* some constants have value in a2, some in *a1.p, strange. */ @@ -605,42 +588,39 @@ interpret(struct f_inst *what) e = ea_find( (*f_tmp_attrs), what->a2.i ); if ((!e) && (f_flags & FF_FORCE_TMPATTR)) e = ea_find( (*f_rte)->attrs->eattrs, what->a2.i ); - + + if (!e) { + /* Undefined value */ + res.type = T_VOID; + break; + } + switch (what->aux & EAF_TYPE_MASK) { case EAF_TYPE_INT: - if (!e) { - res.type = T_VOID; - break; - } + case EAF_TYPE_ROUTER_ID: res.type = T_INT; res.val.i = e->u.data; break; + case EAF_TYPE_OPAQUE: + res.type = T_ENUM_EMPTY; + res.val.i = 0; + break; case EAF_TYPE_IP_ADDRESS: - if (!e) { - res.type = T_VOID; - break; - } res.type = T_IP; struct adata * ad = e->u.ptr; res.val.px.ip = * (ip_addr *) ad->data; break; case EAF_TYPE_AS_PATH: - if (!e) { - res.type = T_VOID; - break; - } res.type = T_PATH; res.val.ad = e->u.ptr; break; case EAF_TYPE_INT_SET: - if (!e) { - res.type = T_CLIST; - res.val.ad = adata_empty(f_pool); - break; - } res.type = T_CLIST; res.val.ad = e->u.ptr; break; + case EAF_TYPE_UNDEF: + res.type = T_VOID; + break; default: bug("Unknown type in e,a"); } @@ -659,10 +639,14 @@ interpret(struct f_inst *what) l->attrs[0].type = what->aux | EAF_ORIGINATED; switch (what->aux & EAF_TYPE_MASK) { case EAF_TYPE_INT: + case EAF_TYPE_ROUTER_ID: if (v1.type != T_INT) runtime( "Setting int attribute to non-int value" ); l->attrs[0].u.data = v1.val.i; break; + case EAF_TYPE_OPAQUE: + runtime( "Setting opaque attribute is not allowed" ); + break; case EAF_TYPE_IP_ADDRESS: if (v1.type != T_IP) runtime( "Setting ip attribute to non-ip value" ); @@ -765,6 +749,10 @@ interpret(struct f_inst *what) return res; res.type &= ~T_RETURN; break; + case P('c','v'): /* Clear local variables */ + for (sym = what->a1.p; sym != NULL; sym = sym->aux2) + ((struct f_val *) sym->def)->type = T_VOID; + break; case P('S','W'): ONEARG; { @@ -814,7 +802,11 @@ interpret(struct f_inst *what) case P('C','a'): /* Community list add or delete */ TWOARGS; - if (v1.type != T_CLIST) + + /* Replace undefined value with empty community list */ + if (v1.type == T_VOID) + v1.val.ad = adata_empty(f_pool); + else if (v1.type != T_CLIST) runtime("Can't add/delete to non-clist"); if (v2.type != T_PAIR) runtime("Can't add/delete non-pair"); @@ -943,6 +935,7 @@ i_same(struct f_inst *f1, struct f_inst *f2) return 0; f2->a2.p = f1->a2.p; break; + case P('c','v'): break; /* internal instruction */ case P('S','W'): ONEARG; if (!same_tree(f1->a2.p, f2->a2.p)) return 0; break; case P('i','M'): TWOARGS; break; case P('A','p'): TWOARGS; break; |