Commit cc444d96 authored by Jan Maria Matejka's avatar Jan Maria Matejka
Browse files

TMP

parent bf4e5a60
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -829,7 +829,7 @@ term:

 | rtadot dynamic_attr { $$ = f_new_inst_da(fi_ea_get, $2); }

 | term '.' IP { $$ = f_new_inst(fi_ip); $$->a1.p = $1; $$->aux = T_IP; }
 | term '.' IP { $$ = f_new_inst(fi_ip); $$->a1.p = $1; }
 | term '.' LEN { $$ = f_new_inst(fi_length); $$->a1.p = $1; }
 | term '.' MASK '(' term ')' { $$ = f_new_inst(fi_ip_mask); $$->a1.p = $1; $$->a2.p = $5; }
 | term '.' FIRST { $$ = f_new_inst(fi_as_path_first); $$->a1.p = $1; }
+232 −255
Original line number Diff line number Diff line
@@ -396,11 +396,9 @@ F_INST_INTERPRET(rta_set)
  RET_VOID;
}


  break;
  case P('e','a'):	/* Access to extended attributes */
    ACCESS_RTE;
F_INST_INTERPRET(ea_get)
{
  ACCESS_RTE;
  eattr *e = NULL;
  u16 code = what->a2.i;

@@ -413,81 +411,52 @@ F_INST_INTERPRET(rta_set)

  if (!e) {
    /* A special case: undefined int_set looks like empty int_set */
	if ((what->aux & EAF_TYPE_MASK) == EAF_TYPE_INT_SET) {
	  res.type = T_CLIST;
	  res.val.ad = adata_empty(f_pool, 0);
	  break;
	}
    if ((what->aux & EAF_TYPE_MASK) == EAF_TYPE_INT_SET)
      RET(T_CLIST, ad, adata_empty(f_pool, 0));

    /* 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);
	  break;
	}
    if ((what->aux & EAF_TYPE_MASK) == EAF_TYPE_EC_SET)
      RET(T_ECLIST, ad, adata_empty(f_pool, 0));

    /* 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);
	  break;
	}
    if ((what->aux & EAF_TYPE_MASK) == EAF_TYPE_LC_SET)
      RET(T_LCLIST, ad, adata_empty(f_pool, 0));

    /* Undefined value */
	res.type = T_VOID;
	break;
    RET_VOID;
  }

  switch (what->aux & EAF_TYPE_MASK) {
  case EAF_TYPE_INT:
	res.type = T_INT;
	res.val.i = e->u.data;
	break;
    RET(T_INT, i, e->u.data);
  case EAF_TYPE_ROUTER_ID:
	res.type = T_QUAD;
	res.val.i = e->u.data;
	break;
    RET(T_QUAD, i, e->u.data);
  case EAF_TYPE_OPAQUE:
	res.type = T_ENUM_EMPTY;
	res.val.i = 0;
	break;
    RET(T_ENUM_EMPTY, i, 0);
  case EAF_TYPE_IP_ADDRESS:
	res.type = T_IP;
	struct adata * ad = e->u.ptr;
	res.val.px.ip = * (ip_addr *) ad->data;
	break;
    RET(T_IP, px.ip, * (ip_addr *) ( (struct adata *) (e->u.ptr) )->data);
  case EAF_TYPE_AS_PATH:
        res.type = T_PATH;
	res.val.ad = e->u.ptr;
	break;
    RET(T_PATH, ad, e->u.ptr);
  case EAF_TYPE_BITFIELD:
	res.type = T_BOOL;
	res.val.i = !!(e->u.data & BITFIELD_MASK(what));
	break;
    RET(T_BOOL, i, !!(e->u.data & BITFIELD_MASK(what)));
  case EAF_TYPE_INT_SET:
	res.type = T_CLIST;
	res.val.ad = e->u.ptr;
	break;
    RET(T_CLIST, ad, e->u.ptr);
  case EAF_TYPE_EC_SET:
	res.type = T_ECLIST;
	res.val.ad = e->u.ptr;
	break;
    RET(T_ECLIST, ad, e->u.ptr);
  case EAF_TYPE_LC_SET:
	res.type = T_LCLIST;
	res.val.ad = e->u.ptr;
	break;
    RET(T_LCLIST, ad, e->u.ptr);
  case EAF_TYPE_UNDEF:
	res.type = T_VOID;
	break;
    RET_VOID;
  default:
	bug("Unknown type in e,a");
    bug("Unknown type in fi_ea_get");
  }
  RET_VOID;
}
    break;
  case P('e','S'):
    ACCESS_RTE;
    ONEARG;

F_INST_INTERPRET(ea_set)
{
  ACCESS_RTE;
  AI(1);
  struct ea_list *l = lp_alloc(f_pool, sizeof(struct ea_list) + sizeof(eattr));
  u16 code = what->a2.i;

@@ -588,90 +557,98 @@ F_INST_INTERPRET(rta_set)
    l->next = (*f_tmp_attrs);
    (*f_tmp_attrs) = l;
  }
  RET_VOID;
}
    break;
  case 'P':

F_INST_INTERPRET(pref_get) {
  ACCESS_RTE;
    res.type = T_INT;
    res.val.i = (*f_rte)->pref;
    break;
  case P('P','S'):
  RET(T_INT, i, (*f_rte)->pref);
}

F_INST_INTERPRET(pref_set) {
  ACCESS_RTE;
    ONEARG;
  AI(1);
  if (v1.type != T_INT)
    runtime( "Can't set preference to non-integer" );
  if (v1.val.i > 0xFFFF)
    runtime( "Setting preference value out of bounds" );
  f_rte_cow();
  (*f_rte)->pref = v1.val.i;
    break;
  case 'L':	/* Get length of */
    ONEARG;
    res.type = T_INT;
  RET_VOID;
}

F_INST_INTERPRET(length) {
  AI(1);
  switch(v1.type) {
    case T_PREFIX: res.val.i = v1.val.px.len; break;
    case T_PATH:   res.val.i = as_path_getlen(v1.val.ad); break;
    case T_CLIST:  res.val.i = int_set_get_size(v1.val.ad); break;
    case T_ECLIST: res.val.i = ec_set_get_size(v1.val.ad); break;
    case T_LCLIST: res.val.i = lc_set_get_size(v1.val.ad); break;
  case T_PREFIX: RET(T_INT, i, v1.val.px.len);
  case T_PATH:   RET(T_INT, i, as_path_getlen(v1.val.ad));
  case T_CLIST:  RET(T_INT, i, int_set_get_size(v1.val.ad));
  case T_ECLIST: RET(T_INT, i, ec_set_get_size(v1.val.ad));
  case T_LCLIST: RET(T_INT, i, lc_set_get_size(v1.val.ad));
  default: runtime( "Prefix, path, clist or eclist expected" );
  }
    break;
  case P('c','p'):	/* Convert prefix to ... */
    ONEARG;
  RET_VOID;
}

F_INST_INTERPRET(ip) {
  AI(1);
  if (v1.type != T_PREFIX)
    runtime( "Prefix expected" );
    res.type = what->aux;
    switch(res.type) {
      /*    case T_INT:	res.val.i = v1.val.px.len; break; Not needed any more */
    case T_IP: res.val.px.ip = v1.val.px.ip; break;
    default: bug( "Unknown prefix to conversion" );

  RET(T_IP, px.ip, v1.val.px.ip);
}
    break;
  case P('a','f'):	/* Get first ASN from AS PATH */
    ONEARG;

F_INST_INTERPRET(as_path_first) {
  AI(1);
  if (v1.type != T_PATH)
    runtime( "AS path expected" );

    as = 0;
  u32 as = 0;
  as_path_get_first(v1.val.ad, &as);
    res.type = T_INT;
    res.val.i = as;
    break;
  case P('a','l'):	/* Get last ASN from AS PATH */
    ONEARG;
  RET(T_INT, i, as);
}

F_INST_INTERPRET(as_path_last) {
  AI(1);
  if (v1.type != T_PATH)
    runtime( "AS path expected" );

    as = 0;
  u32 as = 0;
  as_path_get_last(v1.val.ad, &as);
    res.type = T_INT;
    res.val.i = as;
    break;
  case P('a','L'):	/* Get last ASN from non-aggregated part of AS PATH */
    ONEARG;
  RET(T_INT, i, as);
}

F_INST_INTERPRET(as_path_last_nag) {
  AI(1);
  if (v1.type != T_PATH)
    runtime( "AS path expected" );

    res.type = T_INT;
    res.val.i = as_path_get_last_nonaggregated(v1.val.ad);
    break;
  case 'r':
    ONEARG;
    res = v1;
    res.type |= T_RETURN;
    return res;
  case P('c','a'): /* CALL: this is special: if T_RETURN and returning some value, mask it out  */
    ONEARG;
    res = interpret(what->a2.p);
    if (res.type == T_RETURN)
  RET(T_INT, i, as_path_get_last_nonaggregated(v1.val.ad));
}

F_INST_INTERPRET(return) {
  AI(1);
  v1.type |= T_RETURN;
  return v1;
}

F_INST_INTERPRET(call) {
  AI(1);
  struct f_val res = interpret(what->a2.p);
  if (res.type == T_RETURN) /* Exception */
    return res;

  res.type &= ~T_RETURN;
    break;
  case P('c','v'):	/* Clear local variables */
  return res;
}

F_INST_INTERPRET(clear_local_vars) {
  for (sym = what->a1.p; sym != NULL; sym = sym->aux2)
    ((struct f_val *) sym->def)->type = T_VOID;
    break;
  RET_VOID;
}


  case P('S','W'):
    ONEARG;
    {