Commit 60da7d89 authored by Jan Maria Matejka's avatar Jan Maria Matejka
Browse files

TMP: rewritten, will fix syntax errors

parent cc444d96
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -133,6 +133,8 @@ struct f_val {
  } val;
};

#define F_VAL_VOID ((struct f_val) { .type = T_VOID })

struct f_dynamic_attr {
  int type;
  int f_type;
+219 −223
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@
//#define FI_INST_PREPROCESS(inst) static struct f_val fi_preprocess_##inst(struct f_inst *what)

#define RET(ftype,member,value) return (struct f_val) { .type = ftype, .val.member = (value) }
#define RET_VOID return (struct f_val) { .type = T_VOID }
#define RET_VOID return F_VAL_VOID
#define RETA(member,value) RET(what->aux, member, value)

#define FI_INST_NUMERIC_BINARY(name,op) \
@@ -648,56 +648,49 @@ F_INST_INTERPRET(clear_local_vars) {
  RET_VOID;
}


  case P('S','W'):
    ONEARG;
    {
F_INST_INTERPRET(switch) {
  AI(1);
  struct f_tree *t = find_tree(what->a2.p, v1);
  if (!t) {
	v1.type = T_VOID;
	t = find_tree(what->a2.p, v1);
    t = find_tree(what->a2.p, F_VAL_VOID);
    if (!t) {
      debug( "No else statement?\n");
      break;
    }
  }
      /* It is actually possible to have t->data NULL */

      res = interpret(t->data);
      if (res.type & T_RETURN)
	return res;
  /* It is actually possible to have t->data NULL */
  return interpret(t->data);
}
    break;
  case P('i','M'): /* IP.MASK(val) */
    TWOARGS;

F_INST_INTERPRET(ip_mask) {
  AI(1); AI(2);

  if (v2.type != T_INT)
    runtime( "Integer expected");
  if (v1.type != T_IP)
    runtime( "You can mask only IP addresses" );
    {

  ip_addr mask = ipa_mkmask(v2.val.i);
      res.type = T_IP;
      res.val.px.ip = ipa_and(mask, v1.val.px.ip);
  RET(T_IP, px.ip, ipa_and(mask, v1.val.px.ip));
}
    break;

  case 'E':	/* Create empty attribute */
    res.type = what->aux;
    res.val.ad = adata_empty(f_pool, 0);
    break;
  case P('A','p'):	/* Path prepend */
    TWOARGS;
F_INST_INTERPRET(empty) {
  RETA(ad, adata_empty(f_pool, 0));
}

F_INST_INTERPRET(path_prepend) {
  AI(1); AI(2);
  if (v1.type != T_PATH)
    runtime("Can't prepend to non-path");
  if (v2.type != T_INT)
    runtime("Can't prepend non-integer");

    res.type = T_PATH;
    res.val.ad = as_path_prepend(f_pool, v1.val.ad, v2.val.i);
    break;
  RET(T_PATH, ad, as_path_prepend(f_pool, v1.val.ad, v2.val.i));
}

  case P('C','a'):	/* (Extended) Community list add or delete */
    TWOARGS;
F_INST_INTERPRET(clist_add_del) {
  AI(1); AI(2);
  if (v1.type == T_PATH)
  {
    struct f_tree *set = NULL;
@@ -722,8 +715,7 @@ F_INST_INTERPRET(clear_local_vars) {
    if (pos && !set)
      runtime("Can't filter integer");

      res.type = T_PATH;
      res.val.ad = as_path_filter(f_pool, v1.val.ad, set, key, pos);
    RET(T_PATH, ad, as_path_filter(f_pool, v1.val.ad, set, key, pos));
  }
  else if (v1.type == T_CLIST)
  {
@@ -746,30 +738,26 @@ F_INST_INTERPRET(clear_local_vars) {
    else
      runtime("Can't add/delete non-pair");

      res.type = T_CLIST;
    switch (what->aux)
    {
    case 'a':
      if (arg_set == 1)
	runtime("Can't add set");
      else if (!arg_set)
	  res.val.ad = int_set_add(f_pool, v1.val.ad, n);
	RET(T_CLIST, ad, int_set_add(f_pool, v1.val.ad, n));
      else
	  res.val.ad = int_set_union(f_pool, v1.val.ad, v2.val.ad);
	break;
	RET(T_CLIST, ad, int_set_union(f_pool, v1.val.ad, v2.val.ad));

    case 'd':
      if (!arg_set)
	  res.val.ad = int_set_del(f_pool, v1.val.ad, n);
	RET(T_CLIST, ad, int_set_del(f_pool, v1.val.ad, n));
      else
	  res.val.ad = clist_filter(f_pool, v1.val.ad, v2, 0);
	break;
	RET(T_CLIST, ad, clist_filter(f_pool, v1.val.ad, v2, 0));

    case 'f':
      if (!arg_set)
	runtime("Can't filter pair");
	res.val.ad = clist_filter(f_pool, v1.val.ad, v2, 1);
	break;
      RET(T_CLIST, ad, clist_filter(f_pool, v1.val.ad, v2, 1));

    default:
      bug("unknown Ca operation");
@@ -788,30 +776,26 @@ F_INST_INTERPRET(clear_local_vars) {
    else if (v2.type != T_EC)
      runtime("Can't add/delete non-ec");

      res.type = T_ECLIST;
    switch (what->aux)
    {
    case 'a':
      if (arg_set == 1)
	runtime("Can't add set");
      else if (!arg_set)
	  res.val.ad = ec_set_add(f_pool, v1.val.ad, v2.val.ec);
	RET(T_ECLIST, ad, ec_set_add(f_pool, v1.val.ad, v2.val.ec));
      else
	  res.val.ad = ec_set_union(f_pool, v1.val.ad, v2.val.ad);
	break;
	RET(T_ECLIST, ad, ec_set_union(f_pool, v1.val.ad, v2.val.ad));

    case 'd':
      if (!arg_set)
	  res.val.ad = ec_set_del(f_pool, v1.val.ad, v2.val.ec);
	RET(T_ECLIST, ad, ec_set_del(f_pool, v1.val.ad, v2.val.ec));
      else
	  res.val.ad = eclist_filter(f_pool, v1.val.ad, v2, 0);
	break;
	RET(T_ECLIST, ad, eclist_filter(f_pool, v1.val.ad, v2, 0));

    case 'f':
      if (!arg_set)
	runtime("Can't filter ec");
	res.val.ad = eclist_filter(f_pool, v1.val.ad, v2, 1);
	break;
      RET(T_ECLIST, ad, eclist_filter(f_pool, v1.val.ad, v2, 1));

    default:
      bug("unknown Ca operation");
@@ -837,47 +821,50 @@ F_INST_INTERPRET(clear_local_vars) {
      if (arg_set == 1)
	runtime("Can't add set");
      else if (!arg_set)
	  res.val.ad = lc_set_add(f_pool, v1.val.ad, v2.val.lc);
	RET(T_LCLIST, ad, lc_set_add(f_pool, v1.val.ad, v2.val.lc));
      else
	  res.val.ad = lc_set_union(f_pool, v1.val.ad, v2.val.ad);
	break;
	RET(T_LCLIST, ad,  lc_set_union(f_pool, v1.val.ad, v2.val.ad));

    case 'd':
      if (!arg_set)
	  res.val.ad = lc_set_del(f_pool, v1.val.ad, v2.val.lc);
	RET(T_LCLIST, ad, lc_set_del(f_pool, v1.val.ad, v2.val.lc));
      else
	  res.val.ad = lclist_filter(f_pool, v1.val.ad, v2, 0);
	break;
	RET(T_LCLIST, ad, lclist_filter(f_pool, v1.val.ad, v2, 0));

    case 'f':
      if (!arg_set)
	runtime("Can't filter lc");
	res.val.ad = lclist_filter(f_pool, v1.val.ad, v2, 1);
	break;
      RET(T_LCLIST, ad, lclist_filter(f_pool, v1.val.ad, v2, 1));

    default:
      bug("unknown Ca operation");
    }
  }
  else
      runtime("Can't add/delete to non-[e|l]clist");
    runtime("Can't add/delete to non-[el]?clist");
}

    break;
F_INST_INTERPRET(roa_check) {
  u32 as;

  ip_addr ip;
  int len;

  case P('R','C'):	/* ROA Check */
  if (what->arg1)
  {
      TWOARGS;
    AI(1); AI(2);
    if ((v1.type != T_PREFIX) || (v2.type != T_INT))
      runtime("Invalid argument to roa_check()");

    ip = v1.val.px.ip;
    len = v1.val.px.len;
    as = v2.val.i;
  }
  else
  {
    ACCESS_RTE;
      v1.val.px.ip = (*f_rte)->net->n.prefix;
      v1.val.px.len = (*f_rte)->net->n.pxlen;
    ip = (*f_rte)->net->n.prefix;
    len = (*f_rte)->net->n.pxlen;

    /* We ignore temporary attributes, probably not a problem here */
    /* 0x02 is a value of BA_AS_PATH, we don't want to include BGP headers */
@@ -893,7 +880,16 @@ F_INST_INTERPRET(clear_local_vars) {
  if (!rtc->table)
    runtime("Missing ROA table");

    res.type = T_ENUM_ROA;
    res.val.i = roa_check(rtc->table, v1.val.px.ip, v1.val.px.len, as);
    break;
  RET(T_ENUM_ROA, i, roa_check(rtc->table, ip, len, as));
}


#undef ACCESS_RTE
#undef BITFIELD_MASK
#undef ARG
#undef AI
#undef FI_INST_INTERPRET
#undef RET
#undef RET_VOID
#undef RETA
#undef FI_INST_NUMERIC_BINARY