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

TMP

parent d9573a40
Loading
Loading
Loading
Loading
+9 −14
Original line number Diff line number Diff line
@@ -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; }
+13 −20
Original line number Diff line number Diff line
@@ -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;
  return ret;
  if (da->type) {
    ret->aux = da->type;
    ret->a2.i = da->ea_code;
  }

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;
  return ret;
}

/*
 * 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;
}
+19 −4
Original line number Diff line number Diff line
@@ -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" );
+68 −3
Original line number Diff line number Diff line
@@ -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);