Commit 67337eb9 authored by Maria Jan Matejka's avatar Maria Jan Matejka

TMP

parent d9573a40
Pipeline #21459 failed with stages
in 9 minutes and 44 seconds
......@@ -12,8 +12,6 @@ CF_HDR
CF_DEFINES
#define P(a,b) ((a << 8) | b)
static inline u32 pair(u32 a, u32 b) { return (a << 16) | b; }
static inline u32 pair_a(u32 p) { return p >> 16; }
static inline u32 pair_b(u32 p) { return p & 0xFFFF; }
......@@ -157,12 +155,11 @@ f_new_lc_item(u32 f1, u32 t1, u32 f2, u32 t2, u32 f3, u32 t3)
}
static inline struct f_inst *
f_generate_empty(struct f_inst *dyn)
f_generate_empty(struct f_dynamic_attr dyn)
{
struct f_inst *e = f_new_inst();
e->code = 'E';
struct f_inst *e = f_new_inst(fi_empty);
switch (dyn->aux & EAF_TYPE_MASK) {
switch (dyn->type & EAF_TYPE_MASK) {
case EAF_TYPE_AS_PATH:
e->aux = T_PATH;
break;
......@@ -179,9 +176,9 @@ f_generate_empty(struct f_inst *dyn)
cf_error("Can't empty that attribute");
}
dyn->code = P('e','S');
dyn->a1.p = e;
return dyn;
struct f_inst *s = f_new_inst(fi_ea_set, dyn);
s->a1.p = e;
return s;
}
......@@ -815,7 +812,7 @@ term:
| rtadot static_attr { $$ = $2; $$->code = 'a'; }
| rtadot dynamic_attr { $$ = $2; $$->code = P('e','a'); }
| rtadot dynamic_attr { $$ = f_new_inst(fi_ea_get, $2); }
| term '.' IP { $$ = f_new_inst(); $$->code = P('c','p'); $$->a1.p = $1; $$->aux = T_IP; }
| term '.' LEN { $$ = f_new_inst(); $$->code = 'L'; $$->a1.p = $1; }
......@@ -945,8 +942,7 @@ cmd:
$$->a1.p = $2;
}
| rtadot dynamic_attr '=' term ';' {
$$ = $2;
$$->code = P('e','S');
$$ = f_new_inst(fi_ea_set, $2);
$$->a1.p = $4;
}
| rtadot static_attr '=' term ';' {
......@@ -962,9 +958,8 @@ cmd:
$$->a1.p = $3;
}
| UNSET '(' rtadot dynamic_attr ')' ';' {
$$ = $4;
$$ = f_new_inst(fi_ea_set, $4);
$$->aux = EAF_TYPE_UNDEF | EAF_TEMP;
$$->code = P('e','S');
$$->a1.p = NULL;
}
| break_command print_list ';' { $$ = f_new_inst(); $$->code = P('p',','); $$->a1.p = $2; $$->a2.i = $1; }
......
......@@ -2,6 +2,7 @@
* Filters: utility functions
*
* Copyright 1998 Pavel Machek <pavel@ucw.cz>
* 2017 Jan Maria Matejka <mq@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
......@@ -13,43 +14,35 @@
#define P(a,b) ((a<<8) | b)
struct f_inst *
f_new_inst(void)
f_new_inst(enum filter_instruction_code fi_code, struct f_dynamic_attr da)
{
struct f_inst * ret;
ret = cfg_alloc(sizeof(struct f_inst));
ret->code = ret->aux = 0;
ret->fi_code = fi_code;
ret->aux = 0;
ret->arg1 = ret->arg2 = ret->next = NULL;
ret->lineno = ifs->lino;
if (da->type) {
ret->aux = da->type;
ret->a2.i = da->ea_code;
}
return ret;
}
struct f_inst *
f_new_dynamic_attr(int type, int f_type UNUSED, int code)
{
/* FIXME: Remove the f_type parameter? */
struct f_inst *f = f_new_inst();
f->aux = type;
f->a2.i = code;
return f;
}
/*
* Generate set_dynamic( operation( get_dynamic(), argument ) )
*/
struct f_inst *
f_generate_complex(int operation, int operation_aux, struct f_inst *dyn, struct f_inst *argument)
f_generate_complex(int operation, int operation_aux, struct f_dynamic_attr da, struct f_inst *argument)
{
struct f_inst *set_dyn = f_new_inst(),
*oper = f_new_inst(),
*get_dyn = dyn;
struct f_inst *set_dyn = f_new_inst(fi_ea_get, da),
*oper = f_new_inst(operation),
*get_dyn = f_new_inst(fi_ea_set, da);
*set_dyn = *get_dyn;
get_dyn->code = P('e','a');
oper->code = operation;
oper->aux = operation_aux;
oper->a1.p = get_dyn;
oper->a2.p = argument;
set_dyn->code = P('e','S');
set_dyn->a1.p = oper;
return set_dyn;
}
......
......@@ -596,6 +596,21 @@ static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS;
return res; \
} while(0)
struct filter_instruction {
struct f_val *(*interpret)(struct f_inst *what);
int (*same)(struct f_inst *f1, struct f_inst *f2);
};
#define FI__DEF(code,interpret,same) \
static struct f_val * _filter_interpret_##code(struct f_inst *what) interpret \
static struct f_val * _filter_same_##code(struct f_inst *what) same
static struct filter_instruction filter_instruction[] = {
#define FI__DO(code) \
[FI_NUMERIC_CODE(code)] = { _filter_interpret_##code, _filter_same_##code },
FI__LIST
};
#define ARG(x,y) \
x = interpret(what->y); \
if (x.type & T_RETURN) \
......@@ -643,13 +658,13 @@ interpret(struct f_inst *what)
if (!what)
return res;
switch(what->code) {
case ',':
switch(what->fi_code) {
case fi_comma:
TWOARGS;
break;
/* Binary operators */
case '+':
case fi_add:
TWOARGS_C;
switch (res.type = v1.type) {
case T_VOID: runtime( "Can't operate with values of type void" );
......@@ -657,7 +672,7 @@ interpret(struct f_inst *what)
default: runtime( "Usage of unknown type" );
}
break;
case '-':
case fi_subtract:
TWOARGS_C;
switch (res.type = v1.type) {
case T_VOID: runtime( "Can't operate with values of type void" );
......
......@@ -14,9 +14,67 @@
#include "nest/route.h"
#include "nest/attrs.h"
/* Filter instruction types */
#define FI_TWOCHAR(a,b) ((a<<8) | b)
#define FI_LIST \
F(comma, 0, ',') \
F(add, 0, '+') \
F(subtract, 0, '-') \
F(multiply, 0, '*') \
F(divide, 0, '/') \
F(and, 0, '&') \
F(or, 0, '|') \
F(pair_consruct, 'm', 'p') \
F(ec_construct, 'm', 'c') \
F(lc_construct, 'm', 'l') \
F(neq, '!', '=') \
F(eq, '=', '=') \
F(lt, 0, '<') \
F(lte, '<', '=') \
F(not, 0, '!') \
F(match, 0, '~') \
F(not_match, '!', '~') \
F(defined, 'd', 'e') \
F(set, 0, 's') \
F(constant, 0, 'c') \
F(variable, 0, 'V') \
F(constant_indirect, 0, 'C') \
F(print, 0, 'p') \
F(condition, 0, '?') \
F(nop, 0, '0') \
F(print_and_die, 'p', ',') \
F(rta_get, 0, 'a') \
F(rta_set, 'a', 'S') \
F(ea_get, 'e', 'a') \
F(ea_set, 'e', 'S') \
F(pref_get, 0, 'P') \
F(pref_set, 'P', 'S') \
F(length, 0, 'L') \
F(prefix_convert, 'c', 'p') \
F(as_path_first, 'a', 'f') \
F(as_path_last, 'a', 'l') \
F(as_path_last_nag, 'a', 'L') \
F(return, 0, 'r') \
F(call, 'c', 'a') \
F(clear_local_vars, 'c', 'V') \
F(switch, 'S', 'W') \
F(ip_mask, 'i', 'M') \
F(empty, 0, 'E') \
F(path_prepend, 'A', 'p') \
F(clist_add_del, 'C', 'a') \
F(roa_check, 'R', 'C')
enum filter_instruction_code {
#define F(c,a,b) \
fi_##c = FI_TWOCHAR(a,b),
FI_LIST
#undef F
};
struct f_inst { /* Instruction */
struct f_inst *next; /* Structure is 16 bytes, anyway */
u16 code;
enum filter_instruction_code fi_code;
u16 aux;
union {
int i;
......@@ -75,13 +133,20 @@ struct f_val {
} val;
};
struct f_dynamic_attr {
int type;
int f_type;
int ea_code;
};
struct filter {
char *name;
struct f_inst *root;
};
struct f_inst *f_new_inst(void);
struct f_inst *f_new_dynamic_attr(int type, int f_type, int code); /* Type as core knows it, type as filters know it, and code of dynamic attribute */
struct f_inst *f_new_inst(enum filter_instruction_code fi_code);
static inline struct f_dynamic_attr f_new_dynamic_attr(int type, int f_type, int code) /* Type as core knows it, type as filters know it, and code of dynamic attribute */
{ return (struct f_dynamic_attr) { .type = type, .f_type = f_type, .code = code }; } /* f_type currently unused; will be handy for static type checking */
struct f_tree *f_new_tree(void);
struct f_inst *f_generate_complex(int operation, int operation_aux, struct f_inst *dyn, struct f_inst *argument);
struct f_inst *f_generate_roa_check(struct symbol *sym, struct f_inst *prefix, struct f_inst *asn);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment